pku2689(筛选素数法)

http://acm.pku.edu.cn/JudgeOnline/problem?id=2689

题意:给出两个数L和U (1<=L< U<=2,147,483,647),并且L-U<=1000000,求这个两个数之间的 连续的两个素数,一对间距最小的,和一对间距最大的,输出就行了。要用素数筛选法做,但是一定要注意数据超过int的范围,我就RE了很久~~~

由于本人是老菜所以这个程序跑了400+ms。。。

#include<iostream> #include<cmath> using namespace std; #define MAX 1001005 __int64 L,U,k; __int64 maxn,minn; __int64 prime[MAX]; __int64 boo[MAX]; __int64 a[MAX]; /*void pre(__int64 x,__int64 y) //RE,不知道出了什么问题。为什么还超出范围呢? { __int64 i,j; k=0; memset(boo,0,sizeof(boo)); //for(i=x; i<=y; i++) // boo[i] = 0; boo[0] = boo[1] = 1; for(i=2; i<=y; i++) { if(boo[i]==0) { for(j=i*i; j<=y; j+=i) { if(boo[j]==0) boo[j] = 1; } } } for(i=x; i<=y; i++) { if(boo[i]==0) a[k++] = i; } } */ void pre(int l,int r) //AC掉;筛选法 { __int64 i,j; for(i=2;i*i<=r;i++)//核心部分. { j=l/i*i; if(j<i*i) j=i*i; if(j<l) j+=i; for(;j<=r;j+=i) prime[j-l]=0; } //int c=0; k=0; for(i=l;i<=r;i++) { if(prime[i-l]) a[k++]=i; } } int main() { __int64 i,j; int flag; __int64 xmin,ymin,xmax,ymax; while(scanf("%I64d%I64d",&L,&U)==2) { memset(prime,1,sizeof(prime)); flag = 0; maxn = -1; minn = INT_MAX; if(L==1) //注意1的情况 L = 2; pre(L,U); if(k<=1) { printf("There are no adjacent primes./n"); continue; } for(i=1; i<k; i++) { if((a[i] - a[i-1]) > maxn) { xmax = a[i-1]; ymax = a[i]; maxn = a[i] - a[i-1]; } if(a[i] - a[i-1] < minn) { xmin = a[i-1]; ymin = a[i]; minn = a[i] - a[i-1]; } } printf("%I64d,%I64d are closest, %I64d,%I64d are most distant./n",xmin,ymin,xmax,ymax); } return 0; } 

下面转贴个跑了16ms的代码~~互相学习天天向上哈……很不错的两次筛选。

#include<iostream> using namespace std; __int64 A,B; __int64 prime[50000],next=0; bool v[50000]; void getPrime() //第一次筛选出来1到 47000直间的素数; { __int64 i,j; for(i=2;i<=47000;i++) { if(!v[i]) { prime[next++]=i; if(i<47000/i) { for(j=i*i;j<=47000;j+=i) v[j]=1; } } } } int main() { getPrime(); __int64 i,j,Re=0; bool res[1001000]; while(scanf("%I64d%I64d",&A,&B)==2) { Re=0; if(A==1) A=2; memset(res,true,sizeof(res)); //第二次筛选出从A到B之间的素数,数i保存在res[i-A]中; for(i=0;i<next&′[i]*prime[i]<=B;i++) { __int64 begin=(A/prime[i])+(A%prime[i]>0); if(begin==1) begin++; for(j=begin*prime[i];j<=B;j+=prime[i]) { res[j-A]=false; } } __int64 m1,m2,m3,m4,small=INT_MAX,large=0,pre=-11; for(i=A;i<=B;i++) { if(res[i-A]) { Re++; if(Re!=1) { if(i-pre<small) {m1=pre,m2=i;small=i-pre;} if(i-pre>large) {m3=pre,m4=i;large=i-pre;} } pre=i; } } if(Re<=1) puts("There are no adjacent primes."); else printf("%I64d,%I64d are closest, %I64d,%I64d are most distant./n",m1,m2,m3,m4); } system("pause"); return 0; }  

你可能感兴趣的:(c,BI,System)