2016春季练习——二次筛

来源:互联网 发布:单页面网站引入js 编辑:程序博客网 时间:2024/04/28 21:34

来源:POJ2689

写了两个小时的题目,最后参考题解了。。。果然几天不写题水平下降。。。

RE的代码:

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int N=50010;const long long INF=0x7fffffff;long long prime1[N],np1;bool isp[N*200];void make_p1(){    long long i,j;    np1=0;    memset(isp,1,sizeof(isp));    isp[0]=isp[1]=0;    for(i=2;i<N;i++){        if(isp[i]){            np1++;            prime1[np1]=i;            for(j=i*i;j<N;j+=i)                isp[j]=0;        }    }}long long l,u;long long prime2[1000100];int np2;void make_p2(){    long long i,j,b;    memset(isp,1,sizeof(isp));    for(i=1;i<=np1;i++){        b=l/prime1[i];        while(b*prime1[i]<l||b<=1)            b++;        for(j=b*prime1[i];j<=u;j+=prime1[i]){            if(j>=l)                isp[j-l]=0;        }    }    if(l==1)        isp[0]=0;}void solve(){    int i;    long long mina=INF,maxn=-INF;    long long minl,minr,maxl,maxr;    make_p2();    np2=0;    for(i=0;i<u;i++){        if(isp[i]){            np2++;            prime2[np2]=i+1;        }    }    if(np2<=l){        cout<<"There are no adjacent primes."<<endl;        return ;    }    else{        for(i=1;i<np2;i++){            if(prime2[i+1]-prime2[i]<mina){                mina=prime2[i+1]-prime2[i];                minl=prime2[i],minr=prime2[i+1];            }            if(prime2[i+1]-prime2[i]>maxn){                maxn=prime2[i+1]-prime2[i];                maxl=prime2[i],maxr=prime2[i+1];            }        }        printf("%lld,%lld are closest, %lld,%lld are most distant.\n",minl,minr,maxl,maxr);    }}int main(){make_p1();while(scanf("%lld%lld",&l,&u)!=EOF){        solve();}return 0;}
DEBUG没发现问题。。。真是醉了。。。主要是RE,真是不敢相信。

AC代码:

#include <cstdio>#include <cstring>#include <cmath>#include <queue>#include <iostream>#include <algorithm>using namespace std;const int INF=1e9;const int maxn=5e4+10;const int maxm=1e6+10;int l,u,prime[maxn],vis[maxn],f[maxm],t;void ini()//求出50000内的素数,int范围内的合数最小质因子必定小于2^16。{    int i,j,k,m;    t=0;    m=(int)sqrt(maxn+0.5);    memset(vis,0,sizeof(vis));    for(i=2;i<=m;i++)    {        if(!vis[i])        {            for(j=i*i;j<maxn;j+=i)            vis[j]=1;        }    }    for(i=2;i<maxn;i++)if(!vis[i])prime[t++]=i;}int main(){    ini();    while(cin>>l>>u)    {        if(l==1)l=2;//注意l=1会出问题。        int i,j,k,a,b;        memset(f,0,sizeof(f));        for(i=0;i<t;i++)        {            a=(l-1)/prime[i]+1;            b=u/prime[i];            for(j=a;j<=b;j++)if(j>1)f[j*prime[i]-l]=1;//[l,u]区间小于1e6,而l,u数值范围为int,所以偏移l们就能用数组存了        }        int p=-1,max_ans=-1,min_ans=INF,x1,y1,x2,y2;        for(i=0;i<=u-l;i++)//暴力枚举。。        {            if(f[i]==0)            {                if(p==-1){p=i;continue;}                if(max_ans<i-p){max_ans=i-p;x1=p+l;y1=i+l;}                if(min_ans>i-p){min_ans=i-p;x2=p+l;y2=i+l;}                p=i;            }        }        if(max_ans==-1)cout<<"There are no adjacent primes."<<endl;        else cout<<x2<<","<<y2<<" are closest, "<<x1<<","<<y1<<" are most distant."<<endl;    }    return 0;}


1 0