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; }