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

POJ 2689 Prime Distance (筛选法平移)

2013年08月05日 ⁄ 综合 ⁄ 共 1179字 ⁄ 字号 评论关闭

题意:给定一个范围,求此范围内任意两个相邻素数的差值,输出最大值和最小值。

题解:1 <= L <= U <= 2^31,U-L >= 1000000 在空间限制的条件下,可以先将[ L, U ] 平移到 [ 0, U-L+1 ]。然后用筛选法做。

注意:筛选的时候由于1不是任何素数的倍数,所以需要特殊处理。

#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;

const int MAX = 1000009;
const int MAX2 = 50000;
int p[MAX2], a[MAX2], pn;
bool f[MAX];

void prime ()
{
    int i, j; pn = 0;
    memset(a,0,sizeof(a));
    for ( i = 2; i < MAX2; i++ )
    {
        if ( !a[i] ) p[pn++] = i;
        for ( j = 0; j < pn && i * p[j] < MAX2 && (p[j] <= a[i] || a[i] == 0); j++ )
            a[i*p[j]] = p[j];
    }
}

void sift ( int L, int U )
{
    int l, r, i, j;
    int s = (int)sqrt(U+0.0);
    memset(f,0,sizeof(f));
    if ( L == 1 ) f[0] = 1; //从1的需要特殊处理,因为1筛不掉

    for ( i = 0; i < pn && p[i] <= s; i++ )
    {
        l = L / p[i];
        r = U / p[i];
        if ( l <= 1 ) l = 2;//素数本身不能被筛掉
        for ( j = l; j <= r; j++ )
        {
            if (j * p[i] >= L && j * p[i] <= U)
                 f[j*p[i]-L] = 1;
        }
    }
}

void count ( int L, int U, int& pnum, int& c1, int& c2, int& d1, int& d2 )
{
    sift(L,U);
    pnum = 0;
    int l, r, t = U - L + 1;
    int mmin = MAX, mmax = -1;
    for ( int i = 0; i < t; i++ )
    {
        if ( !f[i] )
        {
            pnum++;
            if ( pnum == 1 )
                l = r = i;
            if ( pnum >= 2 )
            {
                l = r, r = i;
                if ( mmin > r-l+1 )
                {
                    mmin = r - l + 1;
                    c1 = l, c2 = r;
                }
                if ( mmax < r-l+1 )
                {
                    mmax = r - l + 1;
                    d1 = l, d2 = r;
                }
            }
        }
    }
    c1 += L, c2 += L, d1 += L, d2 += L;
}

int main()
{
    prime();
    int L, U;
    int c1, c2, d1, d2, pnum;
    while ( scanf("%d%d",&L,&U) != EOF )
    {
        count(L,U,pnum,c1,c2,d1,d2);
        if ( pnum >= 2 )
            printf("%d,%d are closest, %d,%d are most distant.\n",c1,c2,d1,d2);
        else
            printf("There are no adjacent primes.\n");
    }
    return 0;
}


抱歉!评论已关闭.