본문 바로가기
공부/알고리즘

백준 #6588 골드바흐의 추측

by silverage 2023. 8. 19.

마지막 수학 문제였다! 이거 다음엔 브루트 포스 부분으로 들어간다.


백준 #6588 골드바흐의 추측

문제

골드바흐의 추측을 검증하는 프로그램 작성
(조건: 백만 이하의 모든 짝수)

4보다 큰 모든 짝수는 두 홀수 소수의 합으로 나타낼 수 있다.

입력

  • 한 개 이상의 입력
  • 각 테스트 케이스는 짝수 정수 n 한개 (6 이상 100만 이하)
  • 마지막에 0 입력 -> 이를 통해 입력 종료

제출 답

import math, sys

max = 1000000
# max = 100
array = [True for i in range(max+1)] # 처음엔 모든 수가 소수(True)인 것으로 초기화
hasGold = False
input = sys.stdin.readline

# 에라토스테네스의 체 알고리즘 
for i in range(2, int(math.sqrt(max))+1): # 2부터 n의 제곱근까지의 모든 수를 확인하며
    if array[i] == True: # i가 소수인 경우 (남은 수인 경우)
        # i를 제외한 i의 모든 배수를 지우기
        j = 2 
        while i*j <= max:
            array[i*j] = False
            j += 1


while True:

    hasGold = False
    inp = int(input().rstrip())

    if inp < 6 or inp > max or inp == 0:
        break

    for i in range(3, max+1, 2):
        if array[i] and array[inp - i]:
            hasGold = True
            print(inp, "=", i, "+", inp-i)
            break

    if not hasGold:
        print("Goldbach's conjecture is wrong.")
        break

일단 이 친구는 여러 개를 입력받는다는 점에서 소수를 하나씩 계속 비교할 수 없었다.
따라서 에라토스테네스의 체 알고리즘을 이용하여 소수를 판별할 수 있는 리스트를 만들었다.

만든 후 이를 계속 반복하여 i값이 소수일 때, n-i 또한 소수이면 되기 때문에 이를 찾아 출력하는 방식으로 진행했다.

이 문제는 시간 초과에 많이 걸려서 신경쓰던 문제였다.


그냥 소수 조건 구해서 하나하나 비교하자니 시간이 너무 걸렸고,
그래서 찾다가 다행히도 에라토스테네스의 체를 찾을 수 있어 이용했다.

그런데 또 시간 초과가 일어나서 어디를 줄일 수 있을까 했을 때, sys.stdin.readline 함수를 찾을 수 있어서 이걸 이용했더니 시간이 조금 더 줄어든 것 같다. 이때 다행히도 채점을 돌렸을 때 맞아서 이 잔인한 시간 초과의 늪에서 살아나올 수 있었다.


아쉬웠던 점

  1. 에라토스테네스의 체 알고리즘의 경우 구글링을 통해 코드를 거의 데려온 것에 지나지 않았다.
    이에 대한 개념은 이해해서 다행이지만 다음에 사용할 때에는 내가 스스로 짤 수 있도록 해야 할 것 같다.
  2. 소수를 구할 때에도 다양한 방법이 있는데 내가 가장 단순한 방법만 생각하려 했던 점.
    이 부분은 내가 계속해서 공부하고, 문제를 풀어가면서 알아봐야 할 내용이라고 생각한다. 추후에 정리하는 글을 만들어도 괜찮지 않을까 싶다.

'공부 > 알고리즘' 카테고리의 다른 글

백준 #2309 일곱 난쟁이  (0) 2023.08.19
백준 #2609 최대공약수와 최소공배수  (0) 2023.08.19
백준 #17425 약수의 합  (0) 2023.08.19
백준 #17427 약수의 합 2  (0) 2023.08.19
백준 #1037 약수  (0) 2023.08.19