티스토리 뷰

PS/BOJ

[Python] [백준] 1644번: 소수의 연속합

개발을해보자 2021. 3. 8. 00:28

www.acmicpc.net/problem/1644

 

1644번: 소수의 연속합

첫째 줄에 자연수 N이 주어진다. (1 ≤ N ≤ 4,000,000)

www.acmicpc.net

 

문제

하나 이상의 연속된 소수의 합으로 나타낼 수 있는 자연수들이 있다. 몇 가지 자연수의 예를 들어 보면 다음과 같다.

  • 3 : 3 (한 가지)
  • 41 : 2+3+5+7+11+13 = 11+13+17 = 41 (세 가지)
  • 53 : 5+7+11+13+17 = 53 (두 가지)

하지만 연속된 소수의 합으로 나타낼 수 없는 자연수들도 있는데, 20이 그 예이다. 7+13을 계산하면 20이 되기는 하나 7과 13이 연속이 아니기에 적합한 표현이 아니다. 또한 한 소수는 반드시 한 번만 덧셈에 사용될 수 있기 때문에, 3+5+5+7과 같은 표현도 적합하지 않다.

자연수가 주어졌을 때, 이 자연수를 연속된 소수의 합으로 나타낼 수 있는 경우의 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 자연수 N이 주어진다. (1 ≤ N ≤ 4,000,000)

출력

첫째 줄에 자연수 N을 연속된 소수의 합으로 나타낼 수 있는 경우의 수를 출력한다.

 

풀이

에라토스테네스의 체 알고리즘과 투 포인터 알고리즘을 사용하여 풀 수 있는 문제이다.

먼저 n까지 존재하는 소수를 prime_number라는 리스트에 넣어준다.

이후 투 포인터 알고리즘을 이용하였다.

  1. 시작점(start)과 끝점(end)이 첫 번째 원소의 인덱스(0)를 가리키도록 한다.

  2. 현재 부분 합과 n과 같다면, 카운트한다.

  3. 현재 부분 합이 n보다 작으면, end를 1 증가시킨다.

  4. 현재 부분 합이 n보다 크거나 같다면, start를 1 증가시킨다.

  5. 모든 경우를 확인할 때까지 2번부터 4번까지의 과정을 반복한다.

 

import math

n = int(input())

prime_number = []
array = [True for _ in range(n + 1)]

for i in range(2, int(math.sqrt(n)) + 1):
    if array[i]:
        j = 2

        while i * j <= n:
            array[i * j] = False
            j += 1

for num in range(2, n + 1):
    if array[num]:
        prime_number.append(num)

count = 0
interval_sum = 0
end = 0

for start in range(len(prime_number)):
    while interval_sum < n and end < len(prime_number):
        interval_sum += prime_number[end]
        end += 1

    if interval_sum == n:
        count += 1
    interval_sum -= prime_number[start]

print(count)

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함