Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 4814 | Accepted: 1282 |
Description
Input
Output
Sample Input
2 17 14 17
Sample Output
2,3 are closest, 7,11 are most distant. There are no adjacent primes.
这道题是学习素数筛法的经典,应用到了区间筛素数。具体思路是先筛出1到sqrt(2147483647)之间的所有素数,然后再通过已经晒好素数筛出给定区间的素数,关于筛素数的问题,我转载了一篇网上一个人总结的素数总结,里面就有关于筛大数区间的素数的算法。虽然说一切都已经具备了,但是这道题我第一次做的时候RUNTIME ERROR了,原因是声明变量的时候用了long,当数据比较大的时候会超,第二次我改成long long,这才A掉。。总之,还有很多要学的东西,继续努力吧!!
代码:
语言:c++
#include<iostream> using namespace std; long long prime[46500],prime1[1000010],pcount,p1count,in[46500],in1[1000010]; int main() { void getsprime(); getsprime();//构建1到46500(即sqrt(2147483647))之间的素数表 void getlprime(long L,long U); long long L,U; while(cin>>L>>U) { getlprime(L,U);//构造给定区间的素数表 if(p1count<2)//假如有筛出的素数中,素数的个数小于2个,那么就一定不可能存在相邻的两个素数 { cout<<"There are no adjacent primes."<<endl; continue; } else { long long min=2147483647,max=-1; long long distant,xmin,ymin,xmax,ymax; for(long i=0;i<p1count-1;++i) { distant=prime1[i+1]-prime1[i]; if(distant<min)//找最小距离的位置 { min=distant; xmin=i; ymin=i+1; } if(distant>max)//找最大距离的位置 { max=distant; xmax=i; ymax=i+1; } } cout<<prime1[xmin]<<','<<prime1[ymin]<<" are closest, "<<prime1[xmax]<<','<<prime1[ymax]<<" are most distant."<<endl; } } return 0; } void getsprime()//快速筛小范围素数 { for(int i=2;i<46500;++i) in[i]=1; for(int i=2;i<46500;++i) { if(!in[i]) continue; for(int j=i*2;j<46500;j+=i) in[j]=0; } pcount=0; for(int i=2;i<46500;++i) if(in[i]) prime[pcount++]=i; } void getlprime(long L,long U) { if(U<46500)//假如区间的最大值就小于46500的话,那么之际用我们刚才求完的就好了 { p1count=0; for(int i=L;i<=U;++i) if(in[i]) prime1[p1count++]=i; } else//筛大数区间内的素数的核心部分 { long long k,size=U-L; for(long i=0;i<=size;++i) in1[i]=1; for(long i=0;i<=pcount&&prime[i]*prime[i]<=U;++i) { k=L/prime[i]; if(k*prime[i]<L) ++k; if(k<=1) ++k; while(k*prime[i]<=U) { in1[k*prime[i]-L]=0; ++k; } } p1count=0; for(long i=0;i<=size;++i) if(in1[i]) prime1[p1count++]=i+L; } }