题目描述:
给定两个整数L和U,你需要在闭区间[L,U]内找到距离最接近的两个相邻质数C1和C2(即C2-C1是最小的),如果存在相同距离的其他相邻质数对,则输出第一对。
同时,你还需要找到距离最远的两个相邻质数D1和D2(即D1-D2是最大的),如果存在相同距离的其他相邻质数对,则输出第一对。
输入格式:
每行输入两个整数L和U,其中L和U的差值不会超过1000000。
输出格式:
对于每个L和U ,输出一个结果,结果占一行。
结果包括距离最近的相邻质数对和距离最远的相邻质数对。(具体格式参照样例)
如果L和U之间不存在质数对,则输出“There are no adjacent primes.”。
数据范围:
1≤L<U≤231-1,R-L≤106
输入样例:
2 17
14 17
输出样例:
2,3 are closest, 7,11 are most distant.
There are no adjacent primes.
思路:
①用筛法求出2~sqrt(R)之间的所有质数。
②标记i*p(ceil(L/p)≤i≤floor(R/p))。
③所有未标记的数就是[L,R]中的质数。对相邻的质数两两比较,找出差最大的。
时间复杂度:O(∑质数p≤sqrt(R)(R-L)/p)=O(sqrt(R)log log sqrt(R)+(R-L)log log R)。
代码如下:
#include<bits/stdc++.h> #define N 1000000+10 #define M 100000+10 using namespace std; int l,r,m; int v[M],prime[M]; bool st[N]; void primes(int n){//线性筛质数 memset(v,0,sizeof(v)); m=0; for(int i=2;i<=n;i++){ if(v[i]==0){ v[i]=i; prime[++m]=i; } for(int j=1;j<=m;j++){ if(prime[j]>v[i]||prime[j]>n/i)break; v[i*prime[j]]=prime[j]; } } } int main(){ primes(100000);//step 1 while(cin>>l>>r){ memset(st,true,sizeof(st)); if(l==1)st[0]=false; for(int i=1;prime[i]<=sqrt(r);i++){ int p=prime[i]; int l1,r1; if(l%p==0)l1=l/p; else l1=l/p+1; r1=floor(r/p); for(int j=max(2,l1);j<=r1;j++) st[j*p-l]=false;//step 2 } int min1=-1,min2=-1,max1=-1,max2=-1; int minn=1e9,maxx=-1; int before; bool t=false; for(int i=0;i<=r-l;i++){ if(!st[i])continue; if(!t){ before=i;t=true; } else{ if(i-before>maxx){ max1=before;max2=i; maxx=i-before; } if(i-before<minn){ min1=before;min2=i; minn=i-before; } before=i; } }//step 3 if(min1==-1)cout<<"There are no adjacent primes."<<endl; else{ cout<<min1+l<<","<<min2+l<<" are closest, " <<max1+l<<","<<max2+l<<" are most distant."<<endl; } } return 0; }
原文地址:https://www.cnblogs.com/zhengchang/p/prime_distance.html
时间: 2024-11-06 03:38:18