POJ2689 Prime Distance

传送门

本题的大意是,每次给定两个int范围内的数l,r,其中r-l <= 1000000,求出[l,r]之内的所有素数距离最近的一对和距离最远的一对。

这个题直接暴力枚举肯定T,于是之后我还有一种沙雕办法,就是先筛出来1~√r之内所有的素数,这样的话就可以来筛区间内的素数了……于是我就又每一个跑了一遍根号算法(我本来以为只枚举素数不会T的)

还是非常稳妥的T了。

于是乎采取一种新的办法,我们预处理出来素数之后,我们可以只枚举在这个区间范围内的数,我们用每个素数去筛掉他们就行了,这样的话就不会T了……
看一下代码。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<vector>
#include<queue>
#define pb push_back
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n')

using namespace std;
typedef long long ll;
const int M = 40005;
const int N = 1000005;
const int INF = 1000000009;
const ll mod = 51123987;

ll read()
{
    ll ans = 0,op = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
    if(ch == '-') op = -1;
    ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
    ans *= 10;
    ans += ch - '0';
    ch = getchar();
    }
    return ans * op;
}

int l,r,pri[N],dpri[N],tot1,tot2,maxn,minn,mip1,mip2,map1,map2;
bool np[N],vis[N];

void euler()
{
    int n = 50000;
    np[1] = 1;
    rep(i,2,n)
    {
    if(!np[i]) pri[++tot1] = i;
    for(int j = 1;i * pri[j] <= n;j++)
    {
        np[i * pri[j]] = 1;
        if(!(i%pri[j])) break;
    }
    }
}

int main()
{
    euler();
    while(scanf("%d %d",&l,&r) != EOF)
    {
    maxn = 0,minn = INF;
    if(l == 1) vis[0] = 1;
    rep(i,1,tot1)
    {
        int g = l / pri[i];
        if(l % pri[i]) g++;
        for(int j = g;j <= r / pri[i];j++) if(j != 1) vis[pri[i] * j - l] = 1; 
    }
    //rep(i,0,r-l) printf("%d ",vis[i]);enter;
    rep(i,0,r-l)
    {
        if(!vis[i]) dpri[++tot2] = i+l;
        if(tot2 <= 1) continue;
        if(dpri[tot2] - dpri[tot2-1] > maxn) maxn = dpri[tot2] - dpri[tot2-1],map1 = dpri[tot2 - 1],map2 = dpri[tot2];
        if(dpri[tot2] - dpri[tot2-1] < minn) minn = dpri[tot2] - dpri[tot2-1],mip1 = dpri[tot2 - 1],mip2 = dpri[tot2];        
    }
    if(tot2 <= 1) printf("There are no adjacent primes.\n");
    else printf("%d,%d are closest, %d,%d are most distant.\n",mip1,mip2,map1,map2);
    rep(i,0,r-l) vis[i] = 0;tot2 = 0;
    }
    return 0;
}

 

posted @ 2018-10-12 08:06  CaptainLi  阅读(150)  评论(0编辑  收藏  举报