原题:1223
题意:
求区间内最近和最远的两个素数
解析:
范围1~MAX,所以不能一次性用素数筛筛完所有可能数,因为即使你是MAX,也只需要判断到sqrt(MAX)是不是MAX的因数,所以我们可以筛1到sqrt(MAX)的素数,然后用这些数再来筛除给定区间的非素数。
代码:
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<vector>
#include<iostream>
#define D long long
#define mmm(a,b) memset(a,b,sizeof(a))
using namespace std;
int isprime[1000009];
vector<int>prime;
vector<D>ans;
void init_prime(){
mmm(isprime,1);
isprime[0]=isprime[1]=0;
int r=(int)sqrt(2147483647)+1;
for(int i=2;i<=r;i++){
if(!isprime)continue;
prime.push_back(i);
for(vector<int>::iterator it=prime.begin();it!=prime.end();it++){
if(i*(*it)>r)break;
isprime[i*(*it)]=0;
if(i%(*it)==0)break;
}
}
}
void init_ans(D l,D r){
ans.clear();
mmm(isprime,1);//isprime[0]代表左边界
for(vector<int>::iterator it=prime.begin();it!=prime.end();it++){
long long i=max((D)2,l%(*it)==0?l/(*it):l/(*it)+1);
while(i*(*it)<=r){
isprime[i*(*it)-l]=0;
//printf("%lld is't prime\n",i*(*it));
i++;
}
if(l==1)isprime[0]=0;//此方法无法删除1
}
for(D i=0;i<=r-l;i++){
if(isprime[i])ans.push_back(i+l);
}
}
void handle(){
if(ans.size()<2){printf("There are no adjacent primesn\n");return;}
D big=0,low=0,MAX,MIN;MAX=MIN=ans[1]-ans[0];
for(int i=1;i<=ans.size()-2;i++){
if(ans[i+1]-ans[i]>MAX){
MAX=ans[i+1]-ans[i];big=i;
}
if(ans[i+1]-ans[i]<MIN){
MIN=ans[i+1]-ans[i];low=i;
}
}
printf("%lld,%lld are closest, %lld,%lld are most distant.\n",ans[low],ans[low+1],ans[big],ans[big+1]);
}
int main(){
init_prime();
D l,r;
while(cin>>l>>r){
init_ans(l,r);
handle();
}
}