//196k 0ms
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
using namespace std;
int main() {
bool is_prim[10001];
memset(is_prim, true, 10001);
for (int i = 2; i < 10001; ++i) {
if (!is_prim[i])
continue;
for (int j = i * 2; j < 10001; j += i) {
if (is_prim[j])
is_prim[j] = false;
}
}
vector<int> prim;
for (int i = 2; i < 10001; ++i) {
if (is_prim[i])
prim.push_back(i );
}
int n;
scanf("%d", &n);
while (n) {
int sum = 2, cnt = 0;
int st = 0, end = 0;
while (prim[end] <= n) {
if (sum == n) {
++cnt, ++end;
sum = sum + prim[end];
}
if (sum < n) {
++end;
sum += prim[end];
}
if (sum > n) {
sum -= prim[st];
++st;
}
}
printf("%d\n", cnt);
scanf("%d", &n);
}
return 0;
}
notes: 题目有两个优化点
1. 空间换时间,由于题目输入是在[2, 10000]之间,因此首先采用筛选法,将所有范围内的质数计算出来并存储,这样对避免了对每个输入重复计算的时间消耗。
2. 由于题目要求是连续的素数组合,因此采用滑动窗口,在查找组合时候能够达到O(n),比二重循环快两个量级。