POJ 2689

YEAH DONG DONG

终于过了。

这样思考,首先,要把所有素数求出来是不可能的。注意到L,R的差仅一百万,那么就可以只求这个范围内的素数了。而筛选范围内的素数,就可以用上一篇的方法,使用若n为合数,则必有素因子在sqrt(n)中。

在筛选范围内的素数2了一次,直接判断每个数是否素数,TLE。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

using namespace std;
const int LPR=50000;
const int Cprime=1000000;
const int inf=(1<<30);

bool isprime[LPR+10];
bool gsprime[Cprime+10];
__int64 prime[LPR],cp;
__int64 gprime[Cprime+10],gp;

void Isprime(){
	memset(isprime,true,sizeof(isprime));
	int e=(int)sqrt(LPR*1.0);
	isprime[0]=isprime[1]=false;
	for(int i=2;i<=e;i++){
		if(isprime[i]){
			for(int j=i*i;j<=LPR;j+=i)
			isprime[j]=false;
		}
	}
}

void Doprime(){
	cp=0;
	for(int i=1;i<=LPR;i++)
	if(isprime[i])
	prime[cp++]=i;
}
/*
void Fprime(__int64 tp){
	for(__int64 i=0;prime[i]*prime[i]<=tp;i++){
		if(tp%prime[i]==0) return ;
	}
	gprime[gp++]=tp;
}
*/
void Fprime(__int64 L,__int64 R){
	memset(gsprime,true,sizeof(gsprime));
	__int64 tp=L;
	if(L==1){
		gsprime[0]=false;
		L++;
	}
	for(__int64 i=0;i<cp;i++){
		if(prime[i]>R) break;
		__int64 s=L/prime[i];
		if(s*prime[i]<L)
		s++;
		bool flag=false;
		for(__int64 p=s*prime[i];p<=R;p+=prime[i]){
			if(s==1&&!flag){
				flag=true;
				continue;
			}
			gsprime[p-tp]=false;
		}
	}
	for(__int64 i=0;i<=R-tp;i++)
	if(gsprime[i])
	gprime[gp++]=i+tp;
}

int main(){
	__int64 L,R; __int64 mind,maxd; __int64 mil,mir,mal,mar;
	Isprime();
	Doprime();
//	cout<<prime[0]<<prime[1]<<prime[2]<<prime[3]<<endl;
	while(scanf("%I64d%I64d",&L,&R)!=EOF){
	//	cout<<L<<' '<<R<<endl;
		mind=inf; maxd=0;
		gp=0;
	/*	for(__int64 i=L;i<=R;i++){
			if(i==2){ gprime[gp++]=i; continue; }
			if(i%2==0) continue;
			Fprime(i);
		}*/
		Fprime(L,R);
		if(gp==0||gp==1)
		printf("There are no adjacent primes.\n");
		else {
			for(int i=0;i<gp-1;i++){
				if(gprime[i+1]-gprime[i]<mind){
					mind=gprime[i+1]-gprime[i];
					mil=gprime[i]; mir=gprime[i+1];
				}
				if(gprime[i+1]-gprime[i]>maxd){
					maxd=gprime[i+1]-gprime[i];
					mal=gprime[i]; mar=gprime[i+1];
				}
			}
			printf("%I64d,%I64d are closest, %I64d,%I64d are most distant.\n",mil,mir,mal,mar);
		}
	}
	return 0;
}

  

posted @ 2014-08-27 23:38  chenjunjie1994  阅读(139)  评论(0编辑  收藏  举报