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