【题意】
一些正整数能够被一个或一些连续的素数表示。有多少个表示给定的数?举个栗子,整数
53
有两个表示法
5+7+11+13+17
和
53
;整数41有三个代表
2+3+5+7+11+13
,
11+13+17
和
41
;整数
3
只有一个表示法,就是
限制条件:
2≤n≤104
【提炼】
求连续的素数序列之和等于一个正整数n,需要不停地反复推进区间的开头和末尾,符合尺取法的条件,遂采用尺取法来做。
【分析】
同上。
【时间复杂度】
O(nloglogn)
被筛法拖后腿了=3=
筛法中关于素数有个有趣的关于时间复杂度的proof,有兴趣的小伙伴右戳 链接
【代码】
/*
coder: Tangent Chang
date: 2017/5/11
A day is a miniature of eternity. by Emerson
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
const int maxn = 10005;
int prime[maxn];
bool is_prime[maxn];
int isPrime() {
int p = 0;
for (int i = 2; i < maxn; ++i) {
is_prime[i] = 1;
}
for (int i = 2; i < maxn; ++i) {
if(is_prime[i]) {
prime[p++] = i;
for (int j = i + i; j < maxn; j += i) {
is_prime[j] = 0;
}
}
}
return p;
}
int main() {
int p = isPrime();
int n;
while (~scanf("%d", &n)) {
int sum = 0, s = 0, t = 0, res = 0;
if (n == 0) break;
while (1) {
while (t < p && sum < n) {
sum += prime[t++];
}
if (sum < n) break;
if (sum == n) res++;
sum -= prime[s++];
}
printf("%d\n", res);
}
return 0;
}