poj 2689 Prime Distance 【数论】【筛法求素数】

来源:互联网 发布:python 爬虫 抓取json 编辑:程序博客网 时间:2024/05/21 01:55

题目链接: 传送门

题目大意: 给你L和R两组数,L和R的范围是2^32,其间隔(即R-L最大为1,000,000.) 。让你求出L和R之间素数的最大间隔和最小的间隔。

比如 2 17。之间的最小素数间隔是2 3,最大的素数间隔是11 17。

要是直接进行一个2^32次方筛法然后在判断是会T的。

我们这样来想,筛法求素数的原理是什么:

/**vis数组标记为0则说明是素数*/int vis[10005];void getPrimevis(int n){    int m=sqrt(n+0.5);    memset(vis,0,sizeof(vis));    for(int i=2; i<=m; i++)     for(int j=i*i; j<=n; j+=i) vis[j]=1;}
我们只用找到m=sqrt(n)内的素数和合数,然后对于1~n中的数如果输1~m中的素数的倍数,则筛掉。

则判断L到R中素数的个数就也不是很难了。

对于这个题目来说

先把m=sqrt(n)中的素数和合数都求出来,对于L~R中的数进行一个判断。比如让你求1000到2000的结果。

先把1000/c[i]的值记为s,在吧2000/c[i]的值记为t,然后对于s到t之间我们用相应的素数c[i]乘s 到 相应的素数c[i]乘t 得到的值减去1000(这样有助于减少数组的大小)。

这样就把L~R的数组转换成了r数组,下面就是一个暴力的搜的过程了。

主要是一些细节的处理,比如1的处理,边界情况的处理,自己向来这种题目写的蛋疼...... 

#include<queue>#include<map>#include<set>#include<vector>#include<stack>#include<ctime>#include<cstring>#include<iostream>#include<stdio.h>#include<cstdlib>#include<functional>#include<cmath>#define LL long longusing namespace std;const int N=50000;int Max=0xfffffff;int a[50100];int r[1000000],b[N+100],z=0;int main(){    int a0,b0,i,j;    for (i=2; i<=N; i++)        if (!a[i])        {            b[++z]=i;            for (j=i*2; j<=N; j+=i) a[j]=1;        }    while (cin>>a0>>b0)    {        memset(r,0,sizeof(r));        int t=0,dis,mmax=-1,mmin=Max,m1,m2;        for (i=1; i<=z; i++)        {            int s,t;            s=(a0-1)/b[i]+1;            t=b0/b[i];            for (j=s; j<=t; j++)                if (j>1) r[j*b[i]-a0]=1; //利用1~50000中的素数,把合数筛掉,转换成r数组        }        int k=-1;        for (i=0; i<=b0-a0; i++)            if (!r[i])  //若是质数            {                if (k!=-1)                {                    dis=i-k;                    if (dis>mmax)                        mmax=dis,m1=i+a0;                    if (dis<mmin)                        mmin=dis,m2=i+a0;                }                if (i+a0!=1) k=i;  //跳过1            }        if (mmax<0)            cout<<"There are no adjacent primes."<<endl;        else        {            cout<<m2-mmin<<','<<m2<<" are closest, ";            cout<<m1-mmax<<','<<m1<<" are most distant."<<endl;        }    }    return 0;}




0 0
原创粉丝点击