반응형
문제
하나 이상의 연속된 소수의 합으로 나타낼 수 있는 자연수들이 있다. 몇 가지 자연수의 예를 들어 보면 다음과 같다.
- 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을 연속된 소수의 합으로 나타낼 수 있는 경우의 수를 출력한다.
예제 입력 120 |
예제 출력 10 |
예제 입력 23 |
예제 출력 21 |
예제 입력 341 |
예제 출력 33 |
예제 입력 453 |
예제 출력 42 |
풀이
n을 소수들의 연속된 부분 수열의 합으로 만들 수 있는 경우의 수를 출력하는 문제이다.
우선 연속된 소수들의 배열을 만들어주어야 하기 때문에, 에라토스테네스의 체를 이용하여 배열을 생성해준다.
에라토스테네스의 체에 관한 자세한 내용은 아래의 포스팅을 참고하길 바란다.
소수의 배열을 완성했다면, 일반적인 부분 수열의 합을 구하는 투 포인터 문제와 같이 풀어주면 된다.
import sys
input = sys.stdin.readline
n = int(input())
arr = []
# 에라토스테네스의 체
a = [False,False] + [True]*(n-1)
for i in range(2,int(n**0.5)+1):
if a[i]:
a[i*2::i] = [False]*((n-i)//i)
# 소수 배열 생성
for i in range(n+1):
if a[i] == True:
arr.append(i)
cnt,summ = 0,0
i,j = 0,0
while(True):
if summ == n:
cnt+=1
if summ > n:
summ -= arr[i]
i+=1
elif j == len(arr):
break
else:
summ += arr[j]
j+=1
print(cnt)
반응형
'알고리즘 연습 > 투 포인터' 카테고리의 다른 글
[🥇5 / 백준 2467 / 파이썬] 용액 (0) | 2021.09.24 |
---|---|
[🥇1 / 백준 1450 / 파이썬] 냅색문제 (MITM) (0) | 2021.09.21 |
[🥇4 / 백준 1806 / 파이썬] 부분합 (0) | 2021.09.15 |
[🥇5 / 백준 2470 / 파이썬] 두 용액 (0) | 2021.09.14 |
[🥈3 / 백준 3273 / 파이썬] 두 수의 합 (0) | 2021.09.14 |