题干
让我们定义Dn 为:Dn=Pn+1−Pn,其中Pi是第i个素数。显然有D1=1,且对于n>1有Dn是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。
现给定任意正整数N(<10^5),请计算不超过N的满足猜想的素数对的个数。
输入格式:
输入在一行给出正整数N。
输出格式:
在一行中输出不超过N的满足猜想的素数对的个数。
输入
20
输出
4
#include <bits/stdc++.h>
#include <math.h>
using namespace std;
/*运行超时:我改进了isSushu()判断素数。
两点: 1.只判断到平方根用double sqrt(n)函数
2.用vector动态数组提前存储几个素数,每次验证出一个素数往里加,以后调用isSushu()的时候只用数组里有的素数去判断,而不是每次+1*/
//判断n是不是素数
vector<int> sushu{2,3,5,7,11};
bool isSushu(int n){
if(n<=3) return true;
for(int i=0;i<sushu.size()&&sushu[i]<int(sqrt(n))+1;i++){
if(n%sushu[i]==0) return false;
}
sushu.push_back(n);
return true;
}
//计算不大于n的相差为2的素数对的个数
int countSushu(int n){
if(n<=3) return 0;
int p1=3,p2=4,m;
int count=0;
bool flag1,flag2;
int gap;
while(p1<=n&&p2<=n){
flag1=isSushu(p1);
if(!flag1) {
p1++;
continue;
}
flag2=isSushu(p2);
if(!flag2) {
p2++;
continue;
}
if(flag1&&flag2){
//cout<<"p1="<<p1<<" p2="<<p2<<endl;
if(p2-p1>0) gap = p2-p1;
else gap=p1-p2;
if(gap==2){ //差为2的素数对 符合条件
count++;
if(p2>p1){
p1=p2;
p2++;
}else{
p2=p1;
p1++;
}
}
else if(gap<2){ //素数对差小于2 大的素数需要后移 +1
if(p1<p2) p2++;
else p1++;
}else{ //素数对 差大于2 小的变大的 大的+1
if(p1<p2){
p1=p2;
p2++;
}else{
p2=p1;
p1++;
}
}
}
}
return count;
}
int main(){
int n;
cin>>n;
int count = countSushu(n);
cout<<count<<endl;
}