백준/ Silver 1 문제 , 백준 파이썬 9020, 골드바흐의 추측
Check Point ! ( 해당사항 ✓체크 )
1. 막힘 없이 수월하게 풀린 문제인가?
2. 1시간이내로 풀렸던 문제인가?
3. 1시간 이상 or 며칠을 두고 풀어봤더니 풀린 문제인가?
4. 시간을 써도 도무지 풀 수 없는 문제인가?
5. 솔루션을 찾아봤는가?
-------------------------------------------------------------------------------------------
난이도 체감
1. 최상
2. 상
3. 중
4. 하
<이해도>
1. 완벽히 이해
2. 다소 헷갈리는 부분들이 있음
3. 이해 못함
<덧붙일 말>
기억하자. 소수문제는 에라토스테네츠의 체 이용
<문제 출처>
https://www.acmicpc.net/problem/9020
9020번: 골드바흐의 추측
1보다 큰 자연수 중에서 1과 자기 자신을 제외한 약수가 없는 자연수를 소수라고 한다. 예를 들어, 5는 1과 5를 제외한 약수가 없기 때문에 소수이다. 하지만, 6은 6 = 2 × 3 이기 때문에 소수가 아
www.acmicpc.net
------------------------------------------------------------------------------------------------------------------------------
소수 문제는 에라토스테네츠의 체를 이용하면 좀 더 수월하게 풀 수 있다.
코드를 살펴보자.
Eratosth=[False]*2+[True]*9999
우선 문제에서 주어진 수의 범위가 10000 까지이므로 에라토스 범위도 10000까지 잡아준다.
이때, 우리는 0과 1이 소수가 아니라는 점을 알고 있기 때문에 미리 False로 선언해준다.
(10000 의 범위이지만 10001 까지 선언해주는 이유는 인덱스를 맞춰서 편하게 사용하기 위함이다.)
이후,
for i in range(2,101): # 에라토스테네스의 체
tmp=i+i
for j in range(tmp,10001,i):
Eratosth[j]=False
에라토스테네스의 체를 실행해주자.
원래 범위를 101 보다 적게 설정해주었는데 이러면 소수로 체크가 안되는 부분들이 있어서 틀렸었다.
안전하게 101 범위까지 돌려준다.
이때, tmp에다가 i+i 를 저장해 그 숫자부터 시작한다. 만약 i 부터 시작하면 i를 포함해버리기 때문에 모든 수가 False 처리되어버리니 주의 하자.
ex) i=2 , tmp=2+2=4, 4부터 시작
for i in range(int(input())):
num=int(input())
divide=num//2
for j in range(divide,0,-1):
if Eratosth[j]==True:
if Eratosth[num-j]==True:
print(j, num-j)
break
이제 본격적으로 수를 입력 받아 처리를 할건데, 반복횟수의 숫자는 따로 이용하지 않으므로 변수 선언 필요 없이 range에서 바로 받아 처리한다.
여기서 num 으로 받은 숫자를 divide 에 절반으로 나누어 넣는 이유는 문제 조건에
만약 가능한 n의 골드바흐 파티션이 여러 가지인 경우에는 두 소수의 차이가 가장 작은 것을 출력한다.
이 조건 때문이다.
예를 들면, 10은 3+7, 5+5 로 구성할 수 있는데 이때,5+5 가 차이가 가장 적으므로 5 5를 출력해야한다.
이를 위해 10 을 절반으로 나눠 5 / 5 부터 시작해서 4 / 6 ... 3 / 7 이렇게 체크를 해주는 거다.
물론 여기선 5 / 5 에서 바로 체크되므로 그 다음숫자들은 볼 필요도 없다.
if Eratosth[j]==True:
if Eratosth[num-j]==True:
두개의 if 문으로 두 수가 모두 소수인지 확인해주고 맞다면 print로 출력후 반드시 break 를 걸어준다.
------------------------------------------------------------------------------------------------------------------------------
정답
import sys
input=sys.stdin.readline
Eratosth=[False]*2+[True]*9999
for i in range(2,101): # 에러노트테네스의 체
tmp=i+i
for j in range(tmp,10001,i):
Eratosth[j]=False
for i in range(int(input())):
num=int(input())
divide=num//2
for j in range(divide,0,-1):
if Eratosth[j]==True:
if Eratosth[num-j]==True:
print(j, num-j)
break
'알고리즘 공부 > 백준 - 파이썬' 카테고리의 다른 글
백준/ Silver 3 문제 , 백준 파이썬 1654 , 랜선 자르기 (0) | 2022.02.03 |
---|---|
백준/ Silver 3 문제 , 백준 파이썬 2805 , 나무 자르기 (0) | 2022.02.03 |
백준/ Silver 5 문제 , 백준 파이썬 11653 , 소인수분해 (0) | 2022.02.03 |
백준/ Silver 4 문제 , 백준 파이썬 2108 , 통계학 (0) | 2022.02.02 |
백준/ Silver 4 문제 , 백준 파이썬 18258 , 큐 2 (0) | 2022.02.02 |