해당 포스팅은 백준 1644번 소수의 연속합 풀이를 다룬다. 문제 링크
코드는 javascript로 작성하였다.
자연수가 주어졌을 때, 이 자연수를 연속된 소수의 합으로 나타낼 수 있는 경우의 수를 구하는 프로그램을 작성하자.
가능한 케이스
3
: 3 (한 가지)41
: 2+3+5+7+11+13 = 11+13+17 = 41 (세 가지)53
: 5+7+11+13+17 = 53 (두 가지)불가능한 케이스 (경우의 수 0)
- 20
:
첫째 줄에 자연수 N이 주어진다. (1 ≤ N ≤ 4,000,000)
첫째 줄에 자연수 N을 연속된 소수의 합으로 나타낼 수 있는 경우의 수를 출력한다.
해당 문제는 n이하의 소수를 구한다음 투포인터
를 통해 n의 연속된 부분합
을 구하는 문제이다.
해당 부분합을 구하기 위해서는 투포인터를 이용해야 하며, 부분합에 대한 점화식은 아래와 같다.
S[n] = 2 + 3 + ... n일 시, sum = S[right] - S[left]
sum < n
right를 1 증가시켜 sum의 값을 늘린다.sum === n
sum > n
const input = require('fs').readFileSync('/dev/stdin').toString();
const target = Number(input);
// 소수 배열 만들기
const isPrime = makePrime(target);
const primeArr = [];
for (let i = 2; i <= isPrime.length; i++) {
if (isPrime[i]) primeArr.push(i)
}
function makePrime(n) {
const numArr = new Array(n+1).fill(true);
for (let i = 2; i <= n; i++) {
if (numArr[i] === 0) continue;
for (let j = i ** 2; j <= n; j += i) {
numArr[j] = false;
}
}
return numArr;
}
// 경우의 수 구하기
let [left, right] = [0,0];
let sum = 0;
let answer = 0;
while (left <= right) {
if (sum < target) {
sum += primeArr[right++];
continue;
}
if (sum === target) answer++;
sum -= primeArr[left++];
}
console.log(answer);