POJ-2689 Prime Distance(两次素数筛+偏移处理)

来源:互联网 发布:淘宝代购怎么设置 编辑:程序博客网 时间:2024/05/21 10:34

题目链接:点击打开链接

题意:求区间[a,b]内距离最小的两个素数和距离最大的两个素数。若存在就输出它们的信息,不存在输出"There are no adjacent primes."

分析:由于a和b的范围可达到int上限,如果采取常规素数筛空间是不够用的,只能采取其它的思路。要筛出int范围内的合数,这些合数的最小质因子一定是小于INF^0.5(小于50000),可以先用常规线性筛筛出50000以内的素数,再利用这些素数筛a到b之间的合数即可,因为b-a不大于10^6,筛选合数时将所有数向左偏移a才能不爆内存。

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>using namespace std;const int maxn=50005;const int maxnum=1000005;bool pri[maxn];   //pri[i]=true表示i是素数int primes[maxn];//primes[i]表示50000以内第i个素数bool s[maxnum];  //s[i-a]=true表示i是合数int k=1;void solve1()  //筛选出50000以内的素数{    memset(pri,true,sizeof pri);    for(int i=2;i<maxn;i++)    {        if(pri[i])        {            primes[k++]=i;            for(int j=i+i;j<maxn;j+=i)                pri[j]=false;        }    }}void solve2(int a,int b)//筛出a到b以内的合数{    for(int i=1;i<k;i++)    {        int p=(a-1)/primes[i]+1;        int q=b/primes[i];        for(int j=p;j<=q;j++)        {            if(j>1)            s[j*primes[i]-a]=true;//表示j*primes[i]是合数,这里采取了偏移        }    }}int main(){    int a,b;    solve1();    while(~scanf("%d%d",&a,&b))    {        if(a==1) a++;        memset(s,false,sizeof s);        solve2(a,b);        int min1=0,min2=0,max1=0,max2=0;        int sum1=0x3f3f3f3f,sum2=-1;        int t=-1;        for(int i=0;i<=b-a;i++)  //求出距离最小的两个素数和距离最大的两个素数        {            if(!s[i])            {                if(t>=0)                {                    if(sum1>i-t)//i-t表示两素数之间的距离                    {                        sum1=i-t;                        min1=t+a;                        min2=i+a;                    }                    if(sum2<i-t)                    {                        sum2=i-t;                        max1=t+a;                        max2=i+a;                    }                }                t=i;            }        }        if(min1==0||min2==0||max1==0||max2==0)            printf("There are no adjacent primes.\n");        else            printf("%d,%d are closest, %d,%d are most distant.\n",min1,min2,max1,max2);    }    return 0;}


0 0