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;
}
原文地址:https://www.cnblogs.com/little-w/p/3294250.html