poj2689Prime Distance

数论之素数。
题意:给定一个区间范围问此范围内所有相邻素数对之间最小的与最大的。
看数据先:lu(及区间范围)为1-int最大值,区间长度不超过1000000.如果按照一般素数筛,则素数太多不可直接算出,况且无法卡数组那么大。所以做一个预处理,也是这个算法核心之一。
先求出1到50000内所有素数(由于lu在interesting范围内,int合数最大的素数因子小于50000)。这是预处理
然后素数筛标记在lu范围内所有合数,(此处需要更改数组,lu值过大需用偏移量)以便后续使用。
根据刚刚标记,即可得到范围内素数,暴力枚举即可得正答案。
几个注意点:

  1. if(l==1)l=2;需调整l为1
    2.for(int j=a;j<=c;j++)if(j>1)sl1[j*preprime[i]-l]=1;需注意判断j是否大于1
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=5e4+10;
const int maxe=1e6+10;
const int inf=0x3f3f3f3f;
int sl[maxn],preprime[maxn],sl1[maxe];int lala;
void pre()
{
    lala=0;
    int n=0;
    memset(sl,0,sizeof(sl));
    int tep=sqrt(maxn+0.5);
    for(int i=2;i<=tep;i++)
        if(!sl[i])
    {for(int j=i*i;j<maxn;j+=i)
            sl[j]=1;}
    for(int i=2;i<maxn;i++)
    if(sl[i]==0)preprime[lala++]=i;
    return;
}
int main()
{
    int l,u;pre();
    while(~scanf("%d%d",&l,&u))
    {
        if(l==1)l=2;
        int x1,x2,y1,y2;int p=-1;
        int maxx=-1,minn=inf;
        memset(sl1,0,sizeof(sl1));
        for(int i=0;i<lala/**/;i++)
        {
            int a=(l-1)/preprime[i]+1;
            int c=u/preprime[i];
            for(int j=a;j<=c;j++)if(j>1)sl1[j*preprime[i]-l]=1;//
        }
        for(int i=0;i<=u-l;i++)
        {
            if(sl1[i]==0)
            {
                if(p==-1){p=i;continue;}
                if(maxx<i-p){maxx=i-p;y1=p+l;y2=i+l;}
                if(minn>i-p){minn=i-p;x1=p+l;x2=i+l;}
                p=i;
                           }
        }
    if(minn==inf){cout<<"There are no adjacent primes."<<endl;continue;}
        else cout<<x1<<","<<x2<<" are closest, "<<y1<<","<<y2<<" are most distant."<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43331783/article/details/88660671
今日推荐