合数总可以由于素数产生。int 范围内的数,它们都有一个 \(\sqrt{int\_max}\) 内的质因子。
因此,筛出 \([1, \sqrt{int\_max}]\) 内的质数,再根据这些质数筛掉 \([l,r]\) 之间的合数就可以了。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int pri[70005], cnt, uu, vv, eee[1000005], din, ans[15];
bool isp[70005], qwq[1000005];
void shai(){
memset(isp, true, sizeof(isp));
isp[0] = isp[1] = false;
for(int i=2; i<=70000; i++)
if(isp[i]){
pri[++cnt] = i;
for(int j=2; i*j<=70000; j++)
isp[i*j] = false;
}
}
void getPrime(){
memset(qwq, true, sizeof(qwq));
din = 0;
for(int i=1; i<=cnt; i++)
for(int j=uu/pri[i]; j<=vv/pri[i]; j++)
if(j!=1 && pri[i]*j>=uu && pri[i]*j<=vv)
qwq[pri[i]*j-uu] = false;
if(uu==1) qwq[0] = false;
for(int i=0; i<=vv-uu; i++)
if(qwq[i])
eee[++din] = i + uu;
}
int main(){
shai();
while(scanf("%d %d", &uu, &vv)!=EOF){
getPrime();
if(din<2) printf("There are no adjacent primes.\n");
else{
int minn=0x3f3f3f3f, maxn=0;
for(int i=2; i<=din; i++){
int p=eee[i]-eee[i-1];
if(p<minn) minn = p, ans[1] = eee[i-1], ans[2] = eee[i];
if(p>maxn) maxn = p, ans[3] = eee[i-1], ans[4] = eee[i];
}
printf("%d,%d are closest, %d,%d are most distant.\n", ans[1], ans[2], ans[3], ans[4]);
}
}
return 0;
}