Sum of Consecutive Prime Numbers(尺取(用到了筛法求素数))

题目链接: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;
}

猜你喜欢

转载自blog.csdn.net/weixin_44049850/article/details/86577858