poj2689兩次篩法
阿新 • • 發佈:2019-02-06
我們都知道一次篩法求1-n之間的素數,這個篩法的演算法複雜度為O(N),但題目中的U,L最大值可為整型上限,用純粹的暴力篩法肯定要超時?怎麼辦,用二次篩法。U和L之間的合數,質因子不超過O(L^0.5),於是用篩法選出50000內的素數即可,因為50000的平方大於整形上線了。再用這些素數去篩出U-L之間的合數,剩下的就是U-L之間的素數了,邊篩邊計算兩個素數之間的差,就OK了。另外,尤其小心的是U為1的情況,做素數題往往1是個坑爹的東西。。。附程式碼:
#include <iostream> #include <cmath> using namespace std; const int N=50000; const int Max=0xfffffff; int r[1000000],a[N+100],b[N+100],z; int main() { int a0,b0,i,j; for (i=2;i<=N;i++) if (!a[i]) { b[++z]=i; for (j=i*2;j<=N;j+=i) a[j]=1; } while (cin>>a0>>b0) { memset(r,0,sizeof(r)); int t=0,dis,mmax=-1,mmin=Max,m1,m2; for (i=1;i<=z;i++) { int s,t; s=(a0-1)/b[i]+1; t=b0/b[i]; for (j=s;j<=t;j++) if (j>1) r[j*b[i]-a0]=1; } int k=-1; for (i=0;i<=b0-a0;i++) if (!r[i]) { if (k!=-1) { dis=i-k; if (dis>mmax) { mmax=dis; m1=i+a0; } if (dis<mmin) { mmin=dis; m2=i+a0; } } if (i+a0!=1) k=i; } if (mmax<0) { cout<<"There are no adjacent primes."<<endl; } else { cout<<m2-mmin<<','<<m2<<" are closest, "; cout<<m1-mmax<<','<<m1<<" are most distant."<<endl; } } return 0; }