其他分享
首页 > 其他分享> > [2022.1.13]UPC-2021级新生个人训练赛第22场-10151 Problem D 连续质数和

[2022.1.13]UPC-2021级新生个人训练赛第22场-10151 Problem D 连续质数和

作者:互联网

问题 D: 连续质数和

时间限制: 1.000 Sec  内存限制: 128 M

题目描述

质数又称素数,是大于 1 的正整数,除了 1 和它本身外不能被其他自然数整除,有无限 个,比如,2、3、5、7 等都是质数,但比如 9 就不是质数,因为它除了能被 1 和它自己整 除外,还能被 3 整除。 
悦悦小朋友对这类质数非常感兴趣,因为他发现有一些数是能通过连续的质数相加得 到的。比如 5+ 7 + 11 + 13 + 17=53,也就是整数 53 可以由连续的质数 5、7、11、13、17 相 加得到。有时相加的方案还不止一种,比如整数 41  就有 3  种不同的连续质数相加方案: 
2+3+5+7+11+13=41,11+13+17=41,还有一种就它本身,即 41=41。但也有的数是没有这样 
相加方案的,比如整数 20 就找不到连续质数相加的方案,虽然 7 + 13 或者 3 + 5 + 5 + 7 的 结果都是 20,但前者没有连续,后者质数被重复相加了 。悦悦在纸上写了 N(1≤N≤100000) 个数,他想知道每一个整数 Mi(2≤Mi≤100000,1≤i≤N)到底有多少种连续质数相加的 方案?请你编程帮助他一下吧。 

输入

输入共 N+1 行。 第 1 行一个整数 N,表示悦悦在纸上写了 N 个整数。 
接下来每行一个整数,其中第 i+1 行表示整数 Mi 

输出

输出共 N 行。 输出的第 i 行表示整数 Mi 有多少种连续质数相加的方案。 

样例输入 

4
2
12
17
20

样例输出

1
1
2
0

提示

样例中悦悦写了4个整数,分别为2,12,17和20。因为2=2,所以2可以找到满足条件的1种方案。
因为5+7=12,所以12有1种方案。
因为2+3+5+7=17,17=17,所以17有2种方案满足条件。
20没有满足条件的方案,所以输出0。

对于30%的数据保证1≤N≤100,2≤Mi≤100。对于50%的数据保证1≤N≤1000,2≤Mi≤1000。
对于100%的数据保证1≤N≤100000,2≤Mi≤100000。

想法:

其实.....好像问题并不是很困难,先用素数筛筛选出1000000以内的素数,然后利用前缀和来计算连续素数和就可以过啦。

但是好多人都时间超限了......这道题在代码实现的过程中要十分注意优化...

让我们来看代码吧?

#include <cstdio>
#define MX 1e9
#define MN -1e9
typedef long long int ll;
using namespace std;
int pri[10000];
int bet[10000];
bool isp[100010];
ll cnt;
inline ll solve(ll tar){           //这是求解过程
    ll i=0,j=0,tol=0;              //其实不用写成函数,直接复制下去就可以。
    do{                        
        j++;
        while(bet[j]-bet[i]>tar)      //这里只用了一层循环,比两层循环的会快一些!
            i++;                      //很多求子列的问题都可以用一层循环完成。
        if(bet[j]-bet[i]==tar)        //那些的问题的共同特点是:
            tol++;                    //如果当前子列不满足条件,相同起点的所有子列都不会满足。
    }while(j>i);                      //也就是说...子列必须是有序的?。
    return tol;                    
}
int main(){
    ll i,j,n,tar;
    bet[cnt]+=pri[cnt];
    for(i=2;i<=100010;i++){               //用埃氏筛筛选素数
        if(isp[i])
            continue;
        pri[++cnt]=i;
        bet[cnt]=pri[cnt]+bet[cnt-1];
        for(j=i;j*i<=100010;j++){
            isp[j*i]= true;
        }
    }
    scanf("%lld",&n);
    for(i=1;i<=n;i++){
        scanf("%lld",&tar);
        printf("%lld\n",solve(tar));
    }
}

我把1也作为素数加进去了......结果错麻了,WA了一整晚.. : (

标签:13,ll,17,质数,Mi,整数,级新生,相加
来源: https://blog.csdn.net/Tochus/article/details/122484775