[Algorithm Problem] 소수의 연속합 (BAEKJOON: 1644번)

Prime Number Subtotal (부분합)

이 문제는 어떠한 자연수 N$(1 \le N \le 4,000,000)$이 주어졌을 때, 연속된 소수의 합으로 표현할 수 있는 경우의 수를 구하는 문제입니다. 언뜻 보면 투 포인터를 이용한 가장 기본적인 형태로 생각할 수 있어 쉬워보이나 연속된 소수 배열을 구해내기가 까다로울 수 있습니다. 그치만 문제를 많이 풀어보신 분들은 곧바로 에라토스테네스 체를 떠올리실 수 있을거라 생각합니다.

에라토스테네스 체를 구한 뒤, 연속된 소수 배열만을 추출해 이전의 투 포인터 알고리즘과 결합하면 문제를 쉽게 풀어낼 수 있습니다.

소스코드

if __name__=="__main__":
    N = int(input())

    # 에라토스테네스 체
    era_che = [True for _ in range(N + 1)]
    era_che[0], era_che[1] = False, False

    # 소수 시작
    num = 2

    # 에라토스테네스 체
    while num * num <= N:
        idx = 2
        while num * idx <= N:
            era_che[num * idx] = False
            idx += 1
        num += 1

    # 소수만 모으기 (index error 방지용 float('inf'))
    era_che = [idx for idx, chk in enumerate(era_che) if chk is True] + [float('inf')]

    # 부분합 경우의 수 계산
    start_pointer = 0
    end_pointer = 0
    partial_sum = era_che[end_pointer]

    # 답
    answer = 0

    while end_pointer < len(era_che) - 1:
        if partial_sum < N:
            end_pointer += 1
            partial_sum += era_che[end_pointer]
        elif partial_sum == N:
            answer += 1
            partial_sum -= era_che[start_pointer]
            start_pointer += 1
        else:
            partial_sum -= era_che[start_pointer]
            start_pointer += 1

    print(answer)

Updated:

Leave a comment