
https://www.acmicpc.net/problem/1644

위 문제의 조건들을 읽고 생각난 풀이 방식은

선택한 수의 배수를 모두 삭제한다. ⇒ 현재는 2를 가르키고 있는데 2를 제외한 2의 배수들을 모두 삭제한다.

다음 지워지지 않은 수를 선택한다. ⇒ 3을 선택하고 선택한 수의 모든 배수를 삭제한다. 이미 지운수는 다시 지우지 않는다.

앞의 과정을 배열의 끝까지 반복한다.

삭제되지 않은 수를 모두 출력한다.

위의 1~3까지의 과정을 예시 입력3인 N이 41일 때를 예시로 설명해보면,
에라토스테네스의 체를 사용하여 1~41사이의 소수 배열을 찾는다.

해당 소수 배열을 이용하여 구간합 배열을 생성한다.

이후 투포인터를 사용하여 구간합이 N이 되는 경우의 수를 모두 카운트 해주는 것이다.





import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // 자연수
int[] p = new int[n+1];
List<Integer> prime = new ArrayList<>();
// 1에서 N까지의 숫자 배열 생성
for (int i = 2; i <= n; i++) {
p[i] = i;
}
// 에라토스테네스의 체를 통해 소수만 골라내기 (2부터 n의 제곱근까지 배수 탐색하면서 지우기)
for (int i = 2; i <= Math.sqrt(n); i++) {
if (p[i] == 0) continue;
for (int j = i + i; j <= n; j += i) {
p[j] = 0; // 배수 지우기
}
}
// 지워지지 않은 값들로 구간합 배열 생성하기
for (int i = 2; i <= n; i++) {
if(p[i] != 0) prime.add(i);
}
// 구간합
int[] A = new int[prime.size() + 1];
for (int i = 1; i <= prime.size(); i++) {
A[i] = A[i-1] + prime.get(i-1);
}
int count = 0; // 연속된 소수의 합으로 나타낼 수 있는 경우의 수
int start = 0, last = 1; // 투포인터
while(start < last && last < A.length) {
int sum = A[last] - A[start];
if (sum < n) {
last++;
} else if (sum > n) {
start++;
} else {
count++;
start++;
last++;
}
}
System.out.println(count);
}
}