题目描述:
让我们定义 dn 为:dn = pn+1 - pn,其中 pi 是第i个素数。显然有 d1=1 且对于n>1有 dn 是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。
现给定任意正整数N (< 105),请计算不超过N的满足猜想的素数对的个数。
输入格式:每个测试输入包含1个测试用例,给出正整数N。
输出格式:每个测试用例的输出占一行,不超过N的满足猜想的素数对的个数。
输入样例:20输出样例:
4
题目分析:
这题目就是在求素数表。首先运用筛选法(思想就是:目前已知2是素数,那么对于后面的所有整数,只要是2的倍数那么就一定不是素数,将其标记为true,筛选出去。下面一个数字3,它没有被筛选出去(标记仍为true)那么它就一定也是素数。然后重复上面的操作,即可找到想要范围内的所有素数,并进行存储)将不超过N的所有素数求出来。然后进行判断,相邻的素数之间的差值为2,即为所求的“素数对”,计数加一,最终输出。请看一下代码:
#include<stdio.h>
const int maxn=100000;
int pnum=0, prime[maxn]; //分别用于计数,按顺序存放素数
bool flag[maxn]={false}; //标记数组,false表明对应下标是素数,否则不是
void find_prime(int num){ //素数表
for(int i=2;i<maxn;i++){
if(i>num)break; /*如果已经超出了题目要求的N,则跳出循环。等于N的时候不能跳出循环,
因为此时的N可能就是个素数。本题目的测试点1就是这个陷阱,读者有可能错在这位置了 */
if(flag[i]==false){
prime[pnum++]=i; //如果是素数则存储到素数表中
for(int j=i+i;j<maxn;j+=i){
flag[j]=true; //在它之后的所有是该素数倍数的整数全部筛选出去。
}
}
}
}
int main()
{
int n,count=0;
scanf("%d",&n);
find_prime(n); //这一句不能忘记,调用了才能制定素数表
for(int i=1;i<pnum;i++){
if(prime[i]-prime[i-1]==2){
count++; //满足条件,计数++;
}
}
printf("%d",count); //输出
}