Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 16488 | Accepted: 4384 |
Description
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
Output
Sample Input
2 17 14 17
Sample Output
2,3 are closest, 7,11 are most distant. There are no adjacent primes.
L和U的範圍很大,所以不能直接使用線性篩,而L和U的距離不超過一百萬,所以可以先找2~sqrt(INF)的素數,再用篩法找L和U之間的素數,這種篩法是找一個區間內的素數,比較經典,具體看代碼:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
#define M 65538
#define LL long long
const int maxn=1000001;
bool visit[M];
bool is[maxn];
int ans[maxn];
LL p[M];
int cnt=0;
void iii()//找2~sqrt(INF)的素數,65537是素數且大於sqrt(2^31-1);
{
memset(visit,true,sizeof(visit));
visit[1]=0;
for(long long i=2; i<M; ++i)
{
if(visit[i]==true)
{
p[cnt++]=i;
for(long long j=i*i; j<M; j+=i)
{
visit[j]=false;
}
}
}
}
int main()
{
int n,m;
iii();
while(~scanf("%d %d",&n,&m))
{
for(int i=0; i<maxn; i++)
is[i]=1;
if (n == 1) n = 2;
int d=sqrt(m+0.5);
for (LL i = 0; i < cnt && p[i]<= d; i++)//區間篩法,找到大於等於n,小於等於m的素數
{
int s = n/ p[i] + (n% p[i] > 0);
if (s == 1) s = 2;
for (LL j = s; j*p[i] <= m; j++)
if (j*p[i] >= n)
is[j*p[i]-n] = 0;
}
int c = 0;
for (int i = 0; i <= m-n; i++)
if (is[i])
ans[c++] = i + n;
if (c < 2)
{
printf("There are no adjacent primes.\n");
continue;
}
else
{
int min1=ans[0],min2=ans[1],max1=ans[0],max2=ans[1];
for(int i=1; i<c-1; i++)
{
if(ans[i+1]-ans[i]<min2-min1)
{
min2=ans[i+1];
min1=ans[i];
}
if(ans[i+1]-ans[i]>max2-max1)
{
max2=ans[i+1];
max1=ans[i];
}
}
printf("%d,%d are closest, %d,%d are most distant.\n",min1,min2,max1,max2);
}
}
return 0;
}