poj-2739-Sum of Consecutive Prime Numbers

传送门
题意:把一个数分解成若干个连续的素数的和,有多少种情况
如 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;
}

你可能感兴趣的:(poj-2739-Sum of Consecutive Prime Numbers)