题目链接:http://poj.org/problem?id=2689
题目描述:
给定两个整数a,b,最大能够到int(4字节)的最大值,现在这个区间[a,b]中,求两个相邻素数,它们的差最小,再求两个相邻的素数,它们的差最大。如果区间里小于两个素数,则输出There are no adjacent primes.
这里基本思想还是很简单,将[a,b]之间的素数筛出来,区间素数筛选,则先筛出一部分素数,然后再用这些素数去筛这个区间的素数。筛完素数之后,扫一遍就能得到结果了。
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std ;
const int MAXM = 1e6+5 ;
const int MAXN = 47000 ;
long long basePri[MAXN], pri[MAXM], baseNum, num ;
bool bp[MAXN], p[MAXM] ;
void getBasePri(){
baseNum = 0 ;
for( int i = 2; i < MAXN; i++ ){
bp[i] = true ;
}
for( int i = 2; i < MAXN; i++ ){
if( bp[i] ){
for( int j = 2*i; j < MAXN; j += i ){
bp[j] = false ;
}
}
}
for( int i = 2; i < MAXN; i++ ){
if( bp[i] ) basePri[baseNum++] = i ;
}
}
//
void getPrim(int x, int y){
num = 0 ;
if( y <= MAXN ){
for( int i = x; i <= y; i++ ){
if( bp[i] ) pri[num++] = i ;
}
}
else{
for( int i = 0; i < MAXM; i++ ){
p[i] = true ;
}
for( int i = 0; i < baseNum && basePri[i]*basePri[i] <= y; i++ ){
long long times = x / basePri[i] ;
if( x % basePri[i] != 0 ) times++ ;
if( times <= 1 ) times++ ;
while( times*basePri[i] <= y ){
p[times*basePri[i]-x] = false ;
times++ ;
}
}
for( int i = 0; i <= y-x; i++ ){
if( p[i] ) pri[num++] = i+x ;
}
}
}
//
int main(){
//freopen("1234.in","r",stdin) ;
getBasePri() ;
int l, u ;
while( scanf("%d%d",&l,&u) != EOF ){
getPrim(l,u) ;
if( num <= 1 ){
printf("There are no adjacent primes.\n") ;
continue ;
}
int min = pri[1]-pri[0], minL = pri[0], minR = pri[1] ;
int max = min, maxL = minL, maxR = minR ;
for( int i = 2; i < num; i++ ){
int tmp = pri[i]-pri[i-1] ;
if( tmp < min ){
minL = pri[i-1] ;
minR = pri[i] ;
min = tmp ;
}
if( tmp > max ){
maxL = pri[i-1] ;
maxR = pri[i] ;
max = tmp ;
}
}
printf("%d,%d are closest, %d,%d are most distant.\n",minL,minR,maxL,maxR) ;
}
return 0 ;
}