给定两个整数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−11≤L<U≤231−1
输入样例:
2 17
14 17
输出样例:
2,3 are closest, 7,11 are most distant.
There are no adjacent primes.
题意:找到给定范围内相邻质数最大和最小的质数对
思路:给定的l,r的范围都达到了1e9,我们直接筛法存不了这么大,但是他的r-l<=1e6,这个时候我们就应该有数学上的抓关键词分析的想法,从这下手
我们可以知道,每个合数肯定是由一个不大于sqrt(n)的素数和一个数的乘积化来的,那么我们就可以求出1-sqrt(r)的素数然后枚举素数再用筛法分别乘以一个数
达到的数说明就是一个合数,没有被乘到标记的说明就是素数
#include <bits/stdc++.h> using namespace std; #define ll long long const int N=1e5+1000,M=1e6+10; ll prime[N],a[N]; int p[M]; int zs(int n)//判定质数 { memset(prime,0,sizeof(prime)); memset(a,0,sizeof(a)); for(int i=2;i<=n;i++) { if (!prime[i]) a[++a[0]]=i; for(int j=i;j<=n/i;j++) prime[i*j]=1; } } int main() { int l,r; while(cin>>l>>r) { zs(sqrt(r)); memset(p,0,sizeof(p)); if (l==1)//1要特判啊 p[0]=1; for(int i=1;i<=a[0];i++) { for(int j=ceil(l/a[i]);j<=floor(r/a[i]);j++)//celi为向上取整,floor为向下取整. if (j!=1) p[a[i]*j-l]=1;//统一减去l } int as=0,max_ans=0,min_ans=1e9; pair<int,int> ans_a,ans_b; for(int i=l;i<=r;i++) if (!p[i-l]) { if (as) { if (max_ans<i-as) { ans_a.first=as; ans_a.second=i; max_ans=i-as; } if (min_ans>i-as) { ans_b.first=as; ans_b.second=i; min_ans=i-as; } } as=i; } if (max_ans==0 && min_ans==1e9) printf("There are no adjacent primes. ");//没有素数 else printf("%d,%d are closest, %d,%d are most distant. ",ans_b.first,ans_b.second,ans_a.first,ans_a.second); } }