题意:给定区间[L,U],求区间的两对素数,分别是距离最小和距离最大的。这里距离就是两个数的差值
思路:预处理筛选出sqrt(2,147,483,647)以内的素数,然后去筛选出[L,U]的合数,最后从[L,U]的素数中扫描答案
这里用int溢出了。坑。。。
code:
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <string> #include <iomanip> #include <queue> #include <vector> #include <set> #include <map> typedef long long LL; #define inf 0x3f3f3f3f #define P system("pause") using namespace std; #define M 50000 int pri[M],psize; int nop[M],isnp[1000005]; LL ans[80000]; LL le,ri; void sieve() { memset(nop,0,sizeof(nop)); psize=0; for(int i=2;i<M;i++) { if(!nop[i]) { pri[psize++]=i; for(int j=i+i;j<M;j+=i) nop[j]=1; } } } void make() { memset(isnp,0,sizeof(isnp)); for(LL i=0;i<psize&&pri[i]*pri[i]<=ri;i++) { LL t=le/pri[i]; while(t*pri[i]<le||t<=1)t++; for(LL j=t*pri[i];j<=ri;j+=pri[i]) { if(j-le>=0)isnp[j-le]=1; } } if(le==1) isnp[0]=1; } void solve() { LL maxi,mini,mina,minb,maxa,maxb; int yes=0; maxi=-inf; mini=inf; make(); for(int i=0;i<=ri-le;i++) { if(isnp[i]==0) { ans[yes++]=i+le; } } if(yes<2) puts("There are no adjacent primes."); else { for(int i=0;i<yes-1;i++) { if(ans[i+1]-ans[i]<mini) { mini=ans[i+1]-ans[i]; mina=ans[i]; minb=ans[i+1]; } if(ans[i+1]-ans[i]>maxi) { maxi=ans[i+1]-ans[i]; maxa=ans[i]; maxb=ans[i+1]; } } printf("%lld,%lld are closest, %lld,%lld are most distant.\n",mina,minb,maxa,maxb); } } int main() { sieve(); while(scanf("%lld%lld",&le,&ri)!=EOF) { solve(); } return 0; }