各种敲错啊啊啊啊……重写了一遍才过的……这个是模版题,用模版来筛出(a,b)区间内的素数
因为n很大,所以不能直接用筛法来求素数,会超时,网上说的办法是先筛出一些素数,然后用这些筛出来的素数来筛后面的素数
我是筛掉了2^16的素数,当所给区间的右端点小于这个值时,就直接用筛出来素数来求
容易错的地方写在注释里面好了……
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define INF 1000000+10
#define MAXN 1000000
#define PRIME 80000//开始把这个一不小心开小了,就RE了。。
#define PRIMETEMP 100000
using namespace std;
bool isprime[MAXN+10];
bool isprimetemp[MAXN+10];
long long prime[PRIME+10];
long long primetemp[PRIMETEMP+10];
long long top;
long long total;
void init(void)
{
long long i,j;
for(i=2;i<=MAXN;i++)
{
if(!isprime[i]) prime[top++]=i;
for(j=0;j<top&&i*prime[j]<=MAXN;j++)
{
isprime[i*prime[j]]=true;
if(i%prime[j]==0) break;
}
}
top--;
isprime[1]=1;//把1,0真正的含义搞反了,导致这里以及后面悲剧
}
void getprime(long long a,long long b)
{
memset(isprimetemp,0,sizeof(isprimetemp));
memset(primetemp,0,sizeof(primetemp));
long long i,k;
total=0;
if(b<=prime[top])
{
for(i=a;i<=b;i++)
{
if(!isprime[i])//这里别忘了是否定呀
{
primetemp[total++]=i;
}
}
total--;
return ;
}
for(i=0;i<=b-a;i++)
isprimetemp[i]=1;
for(i=0;prime[i]*prime[i]<=b&&i<=top;i++)
{
k=a/prime[i];
if(k*prime[i]<a)k++;
if(k<=1)k++;
while(k*prime[i]<=b)
{
isprimetemp[k*prime[i]-a]=0;
k++;
}
}
for(i=0;i<=b-a;i++)
{
if(isprimetemp[i])
primetemp[total++]=i+a;
}
total--;
}
int main(void)
{
init();
long long a,b;
while(scanf("%lld %lld",&a,&b)==2)
{
getprime(a,b);
long long i;
if(total<1)//一开始写成<=,打2,3的时候居然说没有,汗。。
puts("There are no adjacent primes.");
else
{
long long cl,cr,dl,dr;
long long c=INF,d=0;
for(i=1;i<=total;i++)
{
if(primetemp[i]-primetemp[i-1]>d)
{
dl=primetemp[i-1];
dr=primetemp[i];
d=primetemp[i]-primetemp[i-1];
}
if(primetemp[i]-primetemp[i-1]<c)
{
cl=primetemp[i-1];
cr=primetemp[i];
c=primetemp[i]-primetemp[i-1];
}
}
printf("%lld,%lld are closest, %lld,%lld are most distant.\n",cl,cr,dl,dr);
}
}
return 0;
}