AcWing 196. 质数距离
给定两个整数L和U,你需要在闭区间[L,U]内找到距离最接近的两个相邻质数C1和C2(即C2-C1是最小的),如果存在相同距离的其他相邻质数对,则输出第一对。
同时,你还需要找到距离最远的两个相邻质数D1和D2(即D1-D2是最大的),如果存在相同距离的其他相邻质数对,则输出第一对。
思路:
求出[2, sqrt(R)]
的所有质数,对于每个质数p,把[L, R]
中能被p整除的数标记,即标记i * p (ceil(L/p) <= i <= floor(R/p))
最后未被标记的数为[L, R]
的质数
注意:
1不是质数
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#define ll long long
const int N = 65600, M = 1000005;
int v[N], prime[N], vis[M];
//v和vis分别标记[2, sqrt(R)] 和 [L, R]中的质数,其中vis[i]表示l+i
ll l, r;
void primes(int n)
{
memset(v, 0, sizeof(v));
memset(vis, 0, sizeof(vis));
for(int i = 2; i <= n; ++i)
{
if(v[i]) continue;
for(ll j = l/i; j <= r/i; ++j)
{
if(j == 1) continue;//不能把i标记了
vis[i*j - l] = 1;
}
for(int j = i; j <= n/i; ++j) v[i*j] = 1;
}
}
int main(){
while(scanf("%lld%lld", &l, &r) == 2)
{
primes((int)sqrt(r));
ll pre = -1, max = 0, min = M, maxa, maxb = -1, mina, minb;
for(int i = 0; i <= r-l; ++i)
{
if(!vis[i] && l + i != 1)//1不是质数
{
if(i - pre > max && pre != -1)
{
max = i - pre;
maxa = pre;
maxb = i;
}
if(i - pre < min && pre != -1)
{
min = i - pre;
mina = pre;
minb = i;
}
pre = i;
}
}
if(maxb == -1) printf("There are no adjacent primes.\n");
else printf("%lld,%lld are closest, %lld,%lld are most distant.\n", l+mina, l+minb, l+maxa, l+maxb);
}
return 0;
}