链接:点击打开链接
题意:求出给定区间内最近的两个素数和最远的两个素数
代码:
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int prime[50005],num[50005],judge[1000005]; //因为每个n至少有一个不超过根号n的素因子
int main(){ //又因为筛不出那么多的素数,因此筛出根号n的就可以
int i,j,k,l,r,x,y,st,en,cnt,tmp,sign,ans_min,ans_max;
k=0;
memset(prime,0,sizeof(prime));
for(i=2;i<=50000;i++){
if(!prime[i])
num[k++]=i;
for(j=0;j<k&&num[j]*i<=50000;j++){
prime[num[j]*i]=1;
if(i%num[j]==0)
break;
}
} //50000之内的素数
while(scanf("%d%d",&l,&r)!=EOF){
memset(judge,0,sizeof(judge));
if(l==1)
judge[0]=1; //注意l==1时的情况
for(i=0;i<k;i++){
if(num[i]<=r){
st=(int)ceil(l*1.0/num[i]);
en=(int)floor(r*1.0/num[i]);
if(st==1) //st==1相当于就是素数,不用筛
st++;
for(j=st;j<=en;j++)
judge[num[i]*j-l]=1;
}
} //用0~r-l表示l~r中的素数
ans_max=-INF,ans_min=INF;
x=y=cnt=sign=0;
for(i=0;i<=r-l;i++){
if(!judge[i]){
if(!sign){
tmp=i;
sign=1;
}
else{
cnt=i;
if(ans_max<cnt-tmp){
x=i+l;
ans_max=cnt-tmp;
}
if(ans_min>cnt-tmp){
y=i+l;
ans_min=cnt-tmp;
}
tmp=i;
}
}
}
if(ans_min==INF)
puts("There are no adjacent primes.");
else
printf("%d,%d are closest, %d,%d are most distant.\n",y-ans_min,y,x-ans_max,x);
}
return 0;
}