POJ 2689

http://poj.org/problem?id=2689

给两个数,是个区间,求出区间内靠最近的相邻两个素数,和离最远的相邻的两个素数

思路:先筛出50000以内的素数,然后再在给定的区间内以刚刚的素数为基底,筛出区间内的素数。筛的过程中算出区间左值是最小素数的几倍,然后然后不是整数倍,就往前加1(否则算出的数会不在这个区间里,没意义),然后这个整数倍乘以素数已经大于右边了,那就可以直接退出了。接下来直接按素数的叠加去筛

筛完后先找第一个素数,因为在标记的时候把所有的数都标记成了1,所以找到的数有可能是1,但1不是素数,所以进入下一个,然后开始找答案。。。

#include<stdio.h>
__int64 pri[50000],dis[1000010],len=0,p[50000];
int prime()
{
    __int64 i,j;
    for(i=0;i<50000;i++)
    p[i]=1;
    p[0]=p[1]=0;
    for(i=0;i<50000;i++)
    if(p[i])
    {
       pri[len++]=i;
       for(j=2*i;j<50000;j+=i)
       p[j]=0;
    }
}
int main()
{
    __int64 i,j,l,u,a,b,c,d,min,max;
    prime();
    while(scanf("%I64d%I64d",&l,&u)!=EOF)
    {
         for(i=l;i<=u;i++)dis[i-l]=1;//假设全为素数,下面再慢慢删
         for(i=0;i<len;i++)
         {
            j=l/pri[i];
            if(j*pri[i]>u)break;
            if(l%pri[i])j++;
            if(j==1)j++;
            for(;j*pri[i]<=u;j++)
            dis[j*pri[i]-l]=0;
         }
         min=9999999;
         max=0;
         i=0;
         while(!dis[i])i++;
         if(i+l==1)i++;//这里是处理当数据为1,2时是盲区的情况,边界问题。。。 
         for(j=i+1;j<=u-l;j++)
            if(dis[j])
            {
               if(j-i>max)
               {
                   max=j-i;
                   c=i+l;d=j+l;
               }
               if(j-i<min)
               {
                   min=j-i;
                   a=i+l;b=j+l;
               }
               i=j;
            }
         if(min!=9999999&&max!=0)
         printf("%I64d,%I64d are closest, %I64d,%I64d are most distant.
",a,b,c,d);
         else printf("There are no adjacent primes.
");
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/huzhenbo113/p/3266287.html