`
xitonga
  • 浏览: 589201 次
文章分类
社区版块
存档分类
最新评论

POJ 2689 Prime Distance(筛法)

 
阅读更多

题意:求L到R之间的素数距离最小的两个,和距离最大的两个,如果存在几个,则取第一个。(1=<L<R<=2^32)

思路:1、先预处理1到50000的素数(50000^2>2^32).存入prime[50000]中

2、for(i=0;prime[i]*prime[i]<=R;i++)
{
k=L/prime[i];
j=k*prime[i];
if(k<=1)
j=prime[i]+prime[i];
(L<=prime[i]时,如prime[0]=2,L=2;则k=1,j=2,而2是素数故不能筛去,L=1时,k=0,j=0,也不符合)

for(;j<=R;j+=prime[i])
if(j-L>=0)
isprime[j-L]=true;
}

3、代码

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
using namespace std;
#define LL __int64
#define CL(a,b) memset(a,b,sizeof(a))
#define INF 0xfffffff
const int M(50000);
bool is[M],isprime[2000010];
LL prime[M];
void init()
{
	int i,j;
	CL(is,false);
	is[0]=is[1]=true;
	for(i=2;i*i<M;i++)
		if(!is[i])
		{
			for(j=i+i;j<M;j+=i)
				is[j]=true;
		}
	for(i=0,j=0;i<M;i++)
		if(!is[i])
			prime[j++]=i;
//	printf("%d\n",prime[j-1]);
}
void solve(LL L,LL R)
{
	LL i;
	LL j,k,minm,maxm;
	LL x,y,xx,yy,pre;
	CL(isprime,false);
	if(L==1)
		isprime[0]=true;
	for(i=0;prime[i]*prime[i]<=R;i++)
	{
		k=L/prime[i];
		j=k*prime[i];
		if(k<=1)
			j=prime[i]+prime[i];
		for(;j<=R;j+=prime[i])
			if(j-L>=0)
				isprime[j-L]=true;
	}
	minm=INF;
	maxm=0;
	pre=-1;
	x=y=xx=yy=-1;
	for(i=L;i<=R;i++)
		if(!isprime[i-L])
		{
		//	printf("%d ",i);
			if(pre!=-1)
			{
				if(i-pre>maxm)
				{
					maxm=i-pre;
					x=pre;y=i;
				}
				if(i-pre<minm)
				{
					minm=i-pre;
					xx=pre;yy=i;
				}
			}
			pre=i;
		}
//	printf("\n");
	if(x!=-1)
		printf("%I64d,%I64d are closest, %I64d,%I64d are most distant.\n",xx,yy,x,y);
	else
		printf("There are no adjacent primes.\n");
	
}
int main()
{
	LL L,R;
	init();
	while(scanf("%I64d%I64d",&L,&R)!=EOF)
	{
		solve(L,R);
	}
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics