问题描述
蒜头君请你求出区间 [l,r] 上距离最近的相邻的素数对和距离最远的相邻的素数对。3,5 是相邻的素数,2,5 不是相邻的素数。距离定义为 2 个素数的差的绝对值。比如 5,7 距离为 2。
输入格式
输入 2 个整数l,r(1≤l≤r≤8000000)
输出格式
如果 a,b(a< b) 是距离最近的素数对,c,d(c< d) 是距离最远的素数对,按照如下格式输出a,b are closest, c,d are most distant. 。如果最近或者最远有多对,输出 a 和 c 最小的。如果没有相邻是素数对,输出There are no adjacent primes.。
样例输入
3 10
样例输出
3,5 are closest, 3,5 are most distant.
方法一 记录素数之间的距离打表
#include<bits/stdc++.h>
using namespace std;
const int MAX_N=8000009;
bool p[MAX_N];
int dis[MAX_N]={0};
void is_prime()
{
p[0]=p[1]=0;
for(int i=2;i<=MAX_N;i++)
{
p[i]=1;//假定全为素数
}
for(int i=2;i*i<=MAX_N;i++)
{
if(p[i])
{
for(int j=i*i;j<=MAX_N;j+=i)
{
p[j]=0;
}
}
}
int a=2,b;
for(int i=3;i<=MAX_N;i++)
{
if(p[i])
{
b=i;
dis[i]=b-a;
a=b;
}
}
}
int main()
{
is_prime();
int l,r,minx=MAX_N,maxx=-MAX_N;
int a,b,c,d;//a,b为距离最近的素数对,cd为距离最远的素数对
scanf("%d%d",&l,&r);
//cin>>l>>r;
int flag=0;
for(int i=l+1;i<=r;i++)
{
if(dis[i]<minx&&dis[i]>=1)
{
if(i-dis[i]>=l)
{
flag=1;
minx=dis[i];
b=i;
a=i-dis[i];
}
}
if(dis[i]>maxx&&dis[i]>=1)
{
if(i-dis[i]>=l)
{
flag=1;
maxx=dis[i];
d=i;
c=i-dis[i];
}
}
}
if(!flag)
cout<<"There are no adjacent primes."<<endl;
else
cout<<a<<","<<b<<" are closest, "<<c<<","<<d<<" are most distant."<<endl;
return 0;
}
方法二 指针指示
#include<iostream>
#include<cstdio>
using namespace std;
int n;
int is_prime[8000010];
int primeArr[8000010];
//素数筛选法
int prime(int l,int r){
for (int i = 2; i <= r; ++i) {
is_prime[i] = 1;
}
for (int i = 2; i * i <= r; ++i) {
if (is_prime[i]) {
for (int j = i * i; j <= r; j +=i) {
is_prime[j] = 0;
}
}
}
}
int main(){
int l,r;
cin>>l>>r;
prime(l,r);
//遍历一遍is_prim数组 存储区间上是质数的数和质数总数
//遍历一遍数组 双指针更新最大值 最小值
int k = 0;
for(int i=l;i<=r;i++){
if(is_prime[i]){
primeArr[k++] = i;
}
}
// //现在k表示区间上的素数总数
if(k<2){
cout<<"There are no adjacent primes."<<endl;
return 0;
}
int mind = 0x3f3f3f3f;
int maxd = -0x3f3f3f3f;
int d1,d2;
for(int i=0;i<k-1;i++){
int t = primeArr[i+1] - primeArr[i];
if(t < mind){
mind = t;
d1 = i;
}
if(t > maxd){
maxd = t;
d2 = i;
}
}
printf("%d,%d are closest, %d,%d are most distant.\n",primeArr[d1],primeArr[d1+1],primeArr[d2],primeArr[d2+1]);
return 0;
}