给定两个整数L和U,你需要在闭区间[L,U]内找到距离最接近的两个相邻质数C1和C2(即C2-C1是最小的),如果存在相同距离的其他相邻质数对,则输出第一对。同时,你还需要找到距离最远的两个相邻质数D1和D2(即D1-D2是最大的),如果存在相同距离的其他相邻质数对,则输出第一对。
每行输入两个整数L和U,其中L和U的差值不会超过1000000。
对于每个L和U ,输出一个结果,结果占一行。
结果包括距离最近的相邻质数对和距离最远的相邻质数对。(具体格式参照样例)
如果L和U之间不存在质数对,则输出“There are no adjacent primes.”。
数据范围
1≤L 输入样例:
2 17
14 17
R-L<106是问题的突破点,(L,R)之间的所有非质数都可通过(sqrt(L),Sqrt(R))来推出。所以先把1<<16的素数使用线性筛法晒一遍,然后对于在(L,R )区间的数字中合数去掉,剩下的便是素数。逐渐的缩小规模,复杂度106*loglog106 +(R-L)loglog(R-L)
#include
using namespace std;
const int MAXN=2000001,INF=2147483647;
int l,r,a,b;
bool visit[MAXN],p[MAXN];
int newp[MAXN];
int cnt=0,pr[MAXN];
void prime()
{
for(int i=2; i<=sqrt(INF); i++)
{
if(p[i])
continue;
pr[++cnt]=i;
for(int j=2; j<=sqrt(INF)/i; j++)
{
p[i*j]=1;
}
}
}
int main()
{
prime();
while(scanf("%d%d",&l,&r)!=EOF)
{
memset(newp,0,sizeof(newp));
memset(visit,0,sizeof(visit));
if(l==1)visit[0]=1;
for(int i=1; i<=cnt; i++)
{
for(int j=(l/pr[i]); j<=r/pr[i]; j++)
{
if(j>1&&pr[i]*j-l>=0)
visit[pr[i]*j-l]=1;
}
}
int c=0;
for(int i=l; i<=r; i++){
if(!visit[i-l]){
newp[++c]=i;
}
if(i==r) break;
}
int minDelta=INF,maxDelta=0;
int minX1,minX2,maxX1,maxX2;
for(int i=1 ; i<c; i++)
{
int nowDelta=newp[i+1]-newp[i];
if(nowDelta<minDelta){
minDelta=nowDelta;
minX1=newp[i],minX2=newp[i+1];
}
if(nowDelta>maxDelta)
{
maxDelta=nowDelta;
maxX1=newp[i],maxX2=newp[i+1];
}
}
if(minDelta==INF)
printf("There are no adjacent primes.\n");
else
printf("%d,%d are closest, %d,%d are most distant.\n",minX1,minX2,maxX1,maxX2);
}
}
总结一下本题错误点:1、不要将巨大的数组开在函数(无论是主函数还是其他)内。
2、内存有限,不要随心所欲的开,尽可能的将数据离散化。
3、多组输入置空问题。
段错误没脾气了