题意:给你一个范围L到U,(1<=L< U<=2,147,483,647, 且U-L<=1,000,000 ),求这个范围内相差最小和最大的相邻素数。
//小范围素数筛[s, t].
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int INF=0x7fffffff;
const int maxn=50005;
bool isprime[maxn], isprime2[maxn*20];
int prime[maxn], sum, sum2, prime2[maxn*10];
void makeprime(){ //生成[1 , maxn]素数筛
int i,j;
memset(isprime, true, sizeof(isprime));
isprime[1]=0;
for(i=2;i<=(int)sqrt((double)(maxn));i++)
{
if(isprime[i])
{
j=i*2;
while(j<=maxn)
{
isprime[j]=0;
j+=i;
}
}
}
sum=0;
for(i=2; i<maxn; i++)
if(isprime[i])prime[sum++]=i;
}
void makeprime2(int s, int t){ //生成[s , t]素数筛
int i;
long long j;
memset(isprime2, true, sizeof(isprime2));
if(s==1)
isprime2[0]=0;
for(i=0;i<sum;i++)
{
if(prime[i]<s)
j=((s-1)/prime[i]+1)*(long long)prime[i];
else if(prime[i]>t)break;
else {
isprime2[prime[i]-s]=1;
j=2*prime[i];
}
while(j<=t)
{
isprime2[j-s]=0;
j+=prime[i];
}
}
sum2=0;
for(i=0; i<=t-s; i++)
if(isprime2[i])prime2[sum2++]=i+s;
}
int main(){
int i, s, t, mind, maxd, t1, t2;
makeprime();
while(scanf("%d%d", &s, &t)!=EOF){
makeprime2(s, t);
mind=INF;maxd=0;
if(sum2<2){printf("There are no adjacent primes.\n");continue;}
for(i=1; i<sum2; i++){
if(prime2[i]-prime2[i-1]>maxd){
maxd=prime2[i]-prime2[i-1];
t2=i-1;
}
if(prime2[i]-prime2[i-1]<mind){
mind=prime2[i]-prime2[i-1];
t1=i-1;
}
}
printf("%d,%d are closest, %d,%d are most distant.\n",
prime2[t1], prime2[t1+1], prime2[t2], prime2[t2+1]);
}
return 0;
}