质数距离(POJ2689)

题目

给定两个整数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<U≤2^31−1
输入样例:
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<bits/stdc++.h>
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、多组输入置空问题。
段错误没脾气了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值