传送门:戳我
题目大意:给定一个区间,求出该区间内相邻质数中差值最大的和差值最小的,如果有多组解,输出第一组。不够2个质数的输出There are no adjacent primes .
思路:
首先暴力判质数肯定是不行了,筛选法是必须的。然而我们看范围是int范围,如果筛选打表的话光打表就超时了,所以我们要考虑优化。
试想,一个合数,必定是两个数的乘积,两个因数较小的那一个一定是小于sqrt(n)的,也即是说,一个合数的若干质因数,一定有小于sqrt(n)的。换句话说,我们可以用sqrt(n)以内的数据,筛选出0..n中的所有质数。
所以这道题的方法是先暴力筛选出2^16内的质数,然后用这些质数筛选出[L,U]之间的质数,扫描一遍即可。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
const int INF=50000+20;
int l,r,prime[INF],boo[INF],f[1000000+50],t;
int main(){
int m=(int)sqrt(INF+0.5);
memset(boo,0,sizeof(boo));
boo[1]=boo[0]=1;
for(int i=2;i<=m;i++){
if(!boo[i]){
for(int j=i*i;j<INF;j+=i)
boo[j]=1;
}
}
t=0;
for(int i=2;i<INF;i++){
if(!boo[i]) prime[t++]=i;
}
while(cin>>l>>r){
if(l==1){
l++;
}
memset(f,0,sizeof(f));
for(int i=0;i<t;i++){
int a=(l-1)/prime[i]+1;
int b=r/prime[i];
for(int j=a;j<=b;j++)
if(j>1) f[j*prime[i]-l]=1;
}
int pre=-1,Max=0,Min=0x7f7f7f7f;
int x1,y1,x2,y2;
for(int i=0;i<=r-l;i++){
if(f[i]==0){
if(pre==-1){pre=i;continue;}
if(Max<i-pre){Max=i-pre;x1=pre+l;y1=i+l;}
if(Min>i-pre){Min=i-pre;x2=pre+l;y2=i+l;}
pre=i;
}
}
if(Max==0) cout<<"There are no adjacent primes."<<endl;
else cout<<x2<<","<<y2<<" are closest, "<<x1<<","<<y1<<" are most distant."<<endl;
}
return 0;
}