zoukankan      html  css  js  c++  java
  • poj2689 prime distance

    这道题用到二次筛选素数的方法,优化了时间复杂度,不然会超时;区间长度在10^6以内,可用数组标记,再大也不怎么能实现。

    这道题是限制多多的。

    题目出现的主要问题 1、TLE 2、RE

    主要说说RE的问题:

    1、用数组标记L--U的素数时,容易超下界,但是我当时写的代码没什么问题,可证明一定不会超

    2、这个就是个奇葩了

    LL s=(LL)sqrt(U+0.0);
    for(LL i=0;prim[i] <= s;i++)//关键是s的设定
    
    for(LL i=0;prim[i]*prim[i]<=U;i++)//原来写的是这个,果断被坑了
    //后来通过强制转换都不能解决这个问题,一直RE

    3、另一个会出错的例子

    for(int i=1;i<=n;i++)
    for(int j=1;j!=i; j++)
    //但是这个就是思路的问题了,因为for循环里的是跳出判断条件,这个很容易错啊

    4、总结上面的两个问题,以后统一在for循环里面写continue或者是break

    AC的代码:

    #include<iostream>
    #include<string.h>
    #include<stdio.h>
    #include<math.h>
    #define LL long long
    #define maxn 46600
    bool flag[maxn];
    int prim[maxn/3+5];
    bool f[1000000+5];
    LL cnt;
    using namespace std;
    void built()
    {
        cnt=0;
        memset(flag,0,sizeof(flag));
        for(int i=2;i<=maxn;i++)
        {
            if(!flag[i]) prim[cnt++]=i;
            for(int j=0; j<cnt && prim[j]*i<=maxn;j++)
            {
                flag[i*prim[j]]=1;
                if (i%prim[j]==0) break;
            }
        }
        return;
    }
    void builtf(LL L,LL U)
    {
        memset(f,0,sizeof(f));
        LL s=(LL)sqrt(U+0.0);
        if ( L == 1 ) f[0]=1;
        for(LL i=0;prim[i] <= s;i++)
        {
            int sj;
            int p=prim[i];
            if ( p >= L) sj=2;
            else
            {
                if ( L % p == 0) sj=L/p;
                else sj=L/p+1;
            }
            for(LL j=sj;j*p<=U;j++)
            f[j*p-L]=1;//合数是1
        }
    }
    
    int main()
    {
        LL L,U;
        built();
        while(~scanf("%I64d%I64d",&L,&U))
        {
        builtf(L,U);
        LL min1,min2,max1,max2;
        int t=0;
        for(LL i=0;i<=U-L;i++)
        {
            if ( t==0 && !f[i] ) {min1=i,t++;continue;}
            if ( t==1 && !f[i] ) {min2=i,t++;break;}
        }
        if (t<2) printf("There are no adjacent primes.
    ");
        else
        {
            LL dis1=min2-min1;
            LL dis2=dis1;
            LL last=min2;
            max1=min1;max2=min2;
            for(LL i=min2+1;i<=U-L;i++)
            {
                if (!f[i])
                {
                    if(i-last<dis1)
                    {
                        min1=last;
                        min2=i;
                        dis1=min2-min1;
                    }
                    if (i-last>dis2)
                    {
                        max1=last;
                        max2=i;
                        dis2=max2-max1;
                    }
                    last=i;
                }
            }
            printf("%I64d,%I64d are closest, %I64d,%I64d are most distant.
    ",min1+L,min2+L,max1+L,max2+L);
        }
        }
        return 0;
    }
  • 相关阅读:
    Python
    版本控制
    后台
    前端
    提升权限 关闭系统
    SC命令(windows服务开启/禁用)
    获取当前电脑全部网络连接名字
    x64 win64编译环境下ADO链接Access数据库的问题解决
    Netsh命令-网络禁用开启
    windows主机防护
  • 原文地址:https://www.cnblogs.com/little-w/p/3294250.html
Copyright © 2011-2022 走看看