prime distance

来源:互联网 发布:真丝枕套 知乎 编辑:程序博客网 时间:2024/04/30 04:08
The branch of mathematics called number theory is about properties of numbers. One of the areas that has captured the interest of number theoreticians for thousands of years is the question of primality. A prime number is a number that is has no proper factors (it is only evenly divisible by 1 and itself). The first prime numbers are 2,3,5,7 but they quickly become less frequent. One of the interesting questions is how dense they are in various ranges. Adjacent primes are two numbers that are both primes, but there are no other prime numbers between the adjacent primes. For example, 2,3 are the only adjacent primes that are also adjacent numbers. 
Your program is given 2 numbers: L and U (1<=L< U<=2,147,483,647), and you are to find the two adjacent primes C1 and C2 (L<=C1< C2<=U) that are closest (i.e. C2-C1 is the minimum). If there are other pairs that are the same distance apart, use the first pair. You are also to find the two adjacent primes D1 and D2 (L<=D1< D2<=U) where D1 and D2 are as distant from each other as possible (again choosing the first pair if there is a tie).
Input
Each line of input will contain two positive integers, L and U, with L < U. The difference between L and U will not exceed 1,000,000.
Output
For each L and U, the output will either be the statement that there are no adjacent primes (because there are less than two primes between the two given numbers) or a line giving the two pairs of adjacent primes.
Sample Input
2 17
14 17
Sample Output
2,3 are closest, 7,11 are most distant.

There are no adjacent primes.


 


此题充分体现了我马大哈的本性............囧rz~~~~~~~~

基本思路:合数都存在开根号之后以内的因子,所以可以第一次在50000左右以内筛选,然后再由这当中的筛出来的素数筛选后面范围的素数

注意:1.int型可能会溢出(不知道为何会超时 -_- !!)

    2.考虑好边界的情况,把含1的情况筛去

AC代码如下,还不够精简:

#include<stdio.h>#include<math.h>#include<stdint.h>#include<stdbool.h>#include<string.h>#define N 1000005int prime[N];int prime1[N];bool flag1[N];bool flag2[N];int count=0;void set_prime( )                              //先把50000以内的筛出来{    int i,j;    memset(flag1,true,sizeof(flag1));    for(i=1;i<=N;i++)        if(i%2==0&&i!=2)flag1[i]=false;    for(i=3;i<=50000;i++)    {        if(flag1[i])            for(j=i*2;j<=50000;j+=i)                flag1[j]=false;    }    for(i=2;i<=50000;i++)        if(flag1[i])prime[count++]=i;}int set_primeS(long long l,long long r)            //如果是在50000以内的话直接打印出来就好了{    int i,cnt1;    for(i=l;i<=r;i++)    {        if(flag1[i]&&i!=1)prime1[cnt1++]=i;    }    return cnt1;}int set_primeL(long long l,long long r)                          //区间范围在50000以后的情况{    long long i,j;    long long k;    int cnt1=0;    memset(flag2,true,sizeof(flag2));    for(i=0;i<count&&(long long)prime[i]*prime[i]<=r;i++)         //根据一个合数有其开根号后的因子,如果此时质因子的平方超过了要筛的右边界,则可以不用进    {                                                               行下去,因为前面已经有因子将其筛过一遍了。例如用2,3,5去筛7~17,3会把15筛掉,所以不用5         k=l/prime[i]+(l%prime[i]!=0);           //注意开始筛左边界的范围,如果是不能整除,则要在l/prime[i]基础上加1;         for(j=prime[i]*k;j<=r;j+=prime[i])      //思路同一次筛法        {            if(j>=l&&flag2[j-l])                flag2[j-l]=false;        }    }    for(j=l;j<=r;j++)    {        if(flag2[j-l]&&j!=1)            prime1[cnt1++]=j;    }    return cnt1;}void find_prime(int cnt1){    int i;    long long min,max;    long long x1,x2,y1,y2;    if(cnt1>=2)    {        max=0;        min=prime1[1]-prime1[0];        for(i=cnt1-2;i>=0;i--)        {            if(prime1[i+1]-prime1[i]>=max){max=prime1[i+1]-prime1[i];x1=prime1[i+1];x2=prime1[i];}            if(prime1[i+1]-prime1[i]<=min){min=prime1[i+1]-prime1[i];y1=prime1[i+1];y2=prime1[i];}        }        printf("%lld,%lld are closest, %lld,%lld are most distant.\n",y2,y1,x2,x1);    }    else        printf("There are no adjacent primes.\n");}int main( ){    long long l,r;    int ret;    set_prime( );    while(scanf("%lld%lld",&l,&r)!=EOF)    {        memset(prime1,0,sizeof(prime1));        if(r<50000)        {           ret=set_primeS(l,r);            find_prime(ret);        }        else        {            ret=set_primeL(l,r);            find_prime(ret);        }    }    return 0;}



0 0
原创粉丝点击