prime distance

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 1000005
int 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;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章