시간 제한 | 메모리 제한 |
2초 | 128MB |
문제
하나 이상의 연속된 소수의 합으로 나타낼 수 있는 자연수들이 있다. 몇 가지 자연수의 예를 들어보면 다음과 같다.
- 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까지의 소수를 먼저 에라토스테네스의 체로 구한다.
첫번째 소수인 2부터 N 이하인 가장 큰 소수까지 차례로 탐색해 연속된 소수의 합이 N 이상이 될 때를 확인해본다.
만들어진 소수의 합이 N과 같다면 경우의 수를 1 증가시키고 N을 넘은 경우 다음 소수부터 새로운 연속합을 구한다.
이것보다 빠른 방법이 있을 것 같지만 어째 시간초과는 안떴다.
아마 C#으로 갔으면 시간초과 떴을듯.
정답 코드
더보기
prime = []
N = int(input())
sieve = [True for i in range(N + 1)]
sieve[0] = False
sieve[1] = False
for i in range(2, N + 1):
if sieve[i]:
cnt = i
prime.append(i)
while True:
cnt += i
if cnt > N:
break
sieve[cnt] = False
count = 0
for i in range(len(prime)):
if prime[i] > N:
break
sum = 0
for j in range(i, len(prime)):
sum += prime[j]
if sum > N:
break
elif sum == N:
count += 1
break
print(count)