现在的位置: 首页 > 综合 > 正文

POJ 2689 筛素数

2017年11月16日 ⁄ 综合 ⁄ 共 1299字 ⁄ 字号 评论关闭

题意:给定区间[L,U],求区间的两对素数,分别是距离最小和距离最大的。这里距离就是两个数的差值

思路:预处理筛选出sqrt(2,147,483,647)以内的素数,然后去筛选出[L,U]的合数,最后从[L,U]的素数中扫描答案

这里用int溢出了。坑。。。

code:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <iomanip>
#include <queue>
#include <vector>
#include <set>
#include <map>
typedef long long LL;
#define inf 0x3f3f3f3f
#define P system("pause")
using namespace std;
#define M 50000
int pri[M],psize;
int nop[M],isnp[1000005];
LL ans[80000];
LL le,ri;
void sieve()
{
    memset(nop,0,sizeof(nop));
    psize=0;
    for(int i=2;i<M;i++)
    {
        if(!nop[i])
        {
            pri[psize++]=i;
            for(int j=i+i;j<M;j+=i)
                nop[j]=1;
        }
    }
}
void make()
{
    memset(isnp,0,sizeof(isnp));
    for(LL i=0;i<psize&&pri[i]*pri[i]<=ri;i++)
    {
        LL t=le/pri[i];
        while(t*pri[i]<le||t<=1)t++;
        for(LL j=t*pri[i];j<=ri;j+=pri[i])
        {
            if(j-le>=0)isnp[j-le]=1;
        }

    }
    if(le==1)
        isnp[0]=1;
}
void solve()
{
    LL maxi,mini,mina,minb,maxa,maxb;
    int yes=0;
    maxi=-inf;
    mini=inf;
    make();
    for(int i=0;i<=ri-le;i++)
    {
        if(isnp[i]==0)
        {
            ans[yes++]=i+le;
        }
    }
    if(yes<2)
        puts("There are no adjacent primes.");
    else
    {
        for(int i=0;i<yes-1;i++)
        {
            if(ans[i+1]-ans[i]<mini)
            {
                mini=ans[i+1]-ans[i];
                mina=ans[i];
                minb=ans[i+1];
            }
            if(ans[i+1]-ans[i]>maxi)
            {
                maxi=ans[i+1]-ans[i];
                maxa=ans[i];
                maxb=ans[i+1];
            }
        }
        printf("%lld,%lld are closest, %lld,%lld are most distant.\n",mina,minb,maxa,maxb);
    }
}
int main()
{
    sieve();
    while(scanf("%lld%lld",&le,&ri)!=EOF)
    {
        solve();
    }
    return 0;
}

抱歉!评论已关闭.