7-43 h0044. 连续素数的和
一些正整数能够表示为一个或多个连续素数的和。给出一个正整数,有多少个这样的表示?例如,整数53有两个表示:5+7+11+13+17和53;整数41有三个表示:2+3+5+7+11+13,11+13+17和41;整数3只有一个表示:3;整数20没有这样的表示。注意加法操作数必须是连续的素数,因此,对于整数20,7+13 和 3+5+5+7 都不是有效的表示。
请写一个程序,对于一个给出的正整数,程序给出连续素数的和的表示数。
输入格式:
输入一个正整数序列,每个数一行,在2到10000之间取值。输入结束以0表示。
输出格式:
输出的每一行对应输入的每一行,除了最后的0。输出的每一行对于一个输入的正整数,给出连续素数的和的表示数。输出中没有其他的字符。
输入样例:
2
3
17
41
20
666
12
53
0
输出样例:
在这里给出相应的输出。例如:
1
1
2
3
0
0
1
2
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
思路分析:
先筛出质数,然后暴力枚举,从第一个质数开始往后面加,如果和大于了输入的数x就break
AC 代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 10010;
int prime[maxn];
bool st[maxn];
int cnt;
//欧拉筛筛质数
void get_prime()
{
for (int i = 2; i <= 10000; i++)
{
if (!st[i]) prime[cnt++] = i;
for (int j = 0; prime[j] <= 10000 / i; j++)
{
st[prime[j] * i] = true;
if (i % prime[j] == 0) break;
}
}
}
int main()
{
get_prime();
int x;
int sum = 0,ans=0;
while (cin>>x,x)
{
ans = 0;
for (int i = 0;i<1229; i++) //10000以内的素数只有1229个,但是下标从0开始所以<1229
{
sum = prime[i];
if (sum > x) continue;
else if (sum == x)
{
ans++;
break;
}
for (int j = i+1; j < 1229; j++)
{
sum += prime[j];
if (sum == x) ans++;
if (sum > x) break;
}
}
cout << ans << "\n";
}
return 0;
}