题目地址: http://poj.org/problem?id=2689
题目思路: 找出int 内所有素数空间上时不允许的,但是题目要求l ,u的差不超过100w ,在空间上还是允许的。
然后先找出5w以内的素数,这样的可以中这些素数作为合数最小的素因子将这个合数筛掉。
几个要注意的地方 【1】 因为l可能很大,j的起点不能去“p*p” 然后比L小就加一个p,想一下如果p=2,l很大会花很多时间的。 【2】 然后就是这个j 要用long long 存 ,因为我们找到的j的初值是p 的倍数中第一个大于等于L的,l很大时可能超long long。 【3】 这个筛法筛去的第一个数是4 所以1要特判 l==1 则 b[0]=1;
【4】 每次输入后要将b归零 【5】 将素数存在新的数组里面时,用数组会比用向量快得多,用向量就会超时。
代码:
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 50000
typedef long long ll;
bool p[N+5];
int prime1[N];
ll prime2[1000000];
bool b[1000010];
int nprime1=0,nprime2=0;
void pre()
{
int len =sqrt(N);
for(int i=2;i<=len;i++)
if(p[i]==0)
for(int j=i*i;j<=N;j+=i)
p[j]=1;
for(int i=2;i<=N;i++)
if(p[i]==0)
prime1[nprime1++]=i;
}
int main()
{
pre();
ll l,u;
while(cin>>l>>u)
{
memset(b,0,sizeof(b));
int cnt=0;
for(int i=0;i<nprime1;i++)
{
ll j=l/prime1[i];
while(j*prime1[i]<l||j<=1) j++;
for(j=j*prime1[i];j<=u;j+=prime1[i])
{
b[j-l]=1;
}
}
if(l==1) b[0]=1;
for(int i=0;i<=u-l;i++)
if(b[i]==0)
{
prime2[cnt++]=i+l;
}
if(cnt>=2)
{
int minv=10000000;
int maxv=0;
ll minr,minl,maxl,maxr;
for(int i=0;i<cnt-1;i++)
{
if(prime2[i+1]-prime2[i]<minv)
{
minl=prime2[i];
minr=prime2[i+1];
minv=minr-minl;
}
if(prime2[i+1]-prime2[i]>maxv)
{
maxl=prime2[i];
maxr=prime2[i+1];
maxv=maxr-maxl;
}
}
cout<<minl<<","<<minr<<" are closest, "<<maxl<<","<<maxr<<" are most distant."<<endl;
// printf("%lld,%lld are closest, %lld,%lld are most distant.\n", minl, minr, maxl, maxr);
}
else
cout<<"There are no adjacent primes."<<endl;
//printf("There are no adjacent primes.\n");
}
}