传送门
题意:把一个数分解成若干个连续的素数的和,有多少种情况
如 41可以分解成 2+3+5+7+11+13, 11+13+17和 41.
先把所有的素数(1-10000)计算出来,放在一个vector内,然后计算前缀和
最后根据前缀和计算出所有的情况
#include <iostream>
#include <cstdio>
#include <iomanip>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#define N 100005
#define E 2.718281828
using namespace std;
vector<int> prime;
bool flag[N+3];
int ans[N], prefix[N];
void Init(){
int i, j, k;
for (i = 1; i <= 10000; i++){
flag[i] = true;
}
flag[1] = false;
for (i = 2; i <= 10000; i++){
if (!flag[i]) continue;
for (j = 2*i; j <= 10000; j+=i){
flag[j] = false;
}
}
prime.clear();
for (i = 2; i <= 10000; i++){
if (flag[i])
prime.push_back(i);
}
int l = prime.size();
prefix[0] = prime[0];
for (i = 1; i < l; i++){
prefix[i] = prefix[i-1] + prime[i];
}
ans[2] = 1;
int start, end, sum;
for (i = 3; i <= 10000; i++){
ans[i] = 0;
start = end = 0;
j = lower_bound(prime.begin(), prime.end(), i)-prime.begin();//计算prime中第一个大于等于i的数的位置
while(end <= j){
sum = prefix[end]-prefix[start]+prime[start];//用前缀和计算出start到end的所有素数的和
if (sum == i){
ans[i]++;
end++;
}else if (sum > i){
start++;
}else{
end++;
}
}
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("1.txt", "r", stdin);
#endif
int i, j, t;
Init();
while(cin >> t){
if (!t){
break;
}
cout << ans[t] << endl;
}
return 0;
}