zoukankan      html  css  js  c++  java
  • poj 2689 Prime Distance(素数筛)

    题目链接:http://poj.org/problem?id=2689

    题意:给出区间l,r(1<=l<r<=2147483647),要找到出相邻素数距离最小和距离最大各一对,如果有多对,输出最初的。

    思路:解决这个题目首先需要将[l,r]范围的所有素数找出来,但是l,r范围太大,全找出来是不可能的。因为题目给出l和r的差不超过1000000,将sqrt(r)内的素数打个表, 再用 它去筛选 [l, r] 内的合数, 然后再遍历一次 [l, r], 记录答案即可,这样找素数时间复杂度为O(sqrt(r)),遍历时间复杂度为O(r-l),不会超时。

    代码

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int maxn=50005;
    const int maxm=1e6+10;
    int prime1[maxn];
    bool  isprime[maxm];
    int nprime1,nprime2;
    ll l,r,prime2[maxm];
    void p1()//打表1~sqrt(r)里的素数 
    {
        nprime1=0;
        memset(isprime,1,sizeof(isprime));
        for(ll i=2;i<maxn;i++)
        {
            if(isprime[i])
                prime1[++nprime1]=i;
            for(int j=1;j<=nprime1;j++)
            {
                if(i*prime1[j]>maxn)
                    break;
                isprime[i*prime1[j]]=0;
                if(i%prime1[j]==0)
                    break;
            }
        }
    }
    
    void p2()
    {
        memset(isprime,1,sizeof(isprime));
        for(ll i=1;i<=nprime1;i++)
        {
            ll sum=l/prime1[i];
            while(sum*prime1[i]<l||sum<=1)//使sum*prime1[i]>=l且不是素数 
                sum++;
            for(ll j=sum*prime1[i];j<=r;j+=prime1[i])
            {
                if(j>=l)//筛掉[l,r]中的合数 
                    isprime[j-l]=0;
            }
        }
        if(l==1)
            isprime[0]=0;
    }
    
    void solve()
    {
        ll maxx=-inf,minx=inf;
        ll minl,minr,maxl,maxr;
        p2();
        nprime2=0;
        for(int i=0;i<=r-l;i++)//遍历[l,r],保存其中的素数。 
        {
            if(isprime[i])
                prime2[++nprime2]=i+l;
        }
        if(nprime2<=1)
            printf("There are no adjacent primes.
    ");
        else
        {
            for(int i=1;i<nprime2;i++)
            {
                if(prime2[i+1]-prime2[i]>maxx)
                {
                    maxx=prime2[i+1]-prime2[i];
                    maxl=prime2[i],maxr=prime2[i+1];
                }
                if(prime2[i+1]-prime2[i]<minx)
                {
                    minx=prime2[i+1]-prime2[i];
                    minl=prime2[i],minr=prime2[i+1];
                }
            }
            printf("%lld,%lld are closest, %lld,%lld are most distant.
    ",minl,minr,maxl,maxr);
        }
    }
    
    int main()
    {
        p1();
        while(scanf("%lld%lld",&l,&r)!=EOF)
        {
            solve();
        }
        return 0;
    }
  • 相关阅读:
    什么是webview
    juqery.fn.extend和jquery.extend
    LeetCode
    5. Longest Palindromic Substring
    42. Trapping Rain Water
    11. Container With Most Water
    621. Task Scheduler
    49. Group Anagrams
    739. Daily Temperatures
    3. Longest Substring Without Repeating Characters
  • 原文地址:https://www.cnblogs.com/xiongtao/p/10738646.html
Copyright © 2011-2022 走看看