题目链接:https://cn.vjudge.net/contest/279225#problem/J
题目大意:就是输入一个n,计算出连续素数相加等于n的序列有几个。
首先就是用到了筛法求素数。筛法求素数的思想就是说一个序列中,当然大于等于2,假设都是素数,然后最小的数是素数,放到素数的框里,这个素数的倍数是合数,筛出去到合数的框里,完了之后又出现了新的最小数,然后这个最小数的倍数还是合数,……,就这样一直筛,一直到筛子里面没有元素为止。
然后把一万以内的素数存到一个数组里,然后就开始尺取,如果尺取到的区间素数的和等于n,那就ans++,然后如果大于了,就left++,如果小于了就right++,注意的是这里不用考虑空区间,也就是left和right可以是相等的,因为素数本身也是一个满足条件的序列。
#include <stdio.h>
#include <string.h>
using namespace std;
int a[10001];
int prime[1500];
int judge_prime()
{
memset(prime,false,sizeof(prime));//先假设所有的数都是素数,赋为0
memset(a,false,sizeof(a));
for(int i=2; i<=10000; i++)
{
if(a[i]==0)
for(int j=i*i; j<=10000; j+=i)
a[j]=1;//然后这个数的倍数一定是合数,赋为1
}
int x=1;
for(int i=2; i<=10000; i++)
{
if(a[i]==0)
{
prime[x]=i;
x++;
}
}
return x;//这里返回的就是10000以内素数的和
}
int main()
{
int n;
int num=judge_prime();
while(~scanf("%d",&n)&&n)
{
int left=0,right=1,ans=0,sum;
while(left<=num&&right<=num)
{
sum=0;
for(int i=left; i<=right; i++)
{
sum+=prime[i];
}
if(sum==n)
ans++;
if(sum>n)
left++;
else
right++;//小于等于的时候就右区间端点右移,如果是等于的话,右移之后就会变大于,然后就执行上一句
}
printf("%d\n",ans);
}
return 0;
}