//http://poj.org/problem?id=2689 #include <bitset> #include <iostream> #include <vector> #include <algorithm> #include <cmath> using namespace std; typedef unsigned int uint; /* 原理: 1) 2的倍数都是合数(2除外) 2) 给定一个N, N*i(i>1)都是合数 算法: 1) 假设所有数都是素数 2) 2的倍数为合数 3) 设3<=N<=sqrt(U)+1且N为奇数,则N * i(i>1)的倍数为合数 */ bool* GetPrimeNumbers(uint L, uint U,bool Cands[]) { const uint N = U-L +1; memset(Cands,1,N); for(uint i = L%2==0?0:1;i<N;i+=2) { Cands[i] = false; } uint end = sqrt((double)U)+1; for(uint i = 3;i<end;i+=2) { if(i>=L&&Cands[i-L]==false) //i是合数,不需要继续筛选 continue; uint j = L/i*i; if(j<L) { j+=i; } if(j==i) j+=i; for(j = j-L;j<N;j+=i) { Cands[j] = false; } } if(L==2) Cands[0] = true; return Cands; } bool GetMinMax(bool * Cands,const uint N,int &C1,int &C2, int&D1,int &D2) { C1 = C2 = D1 =D2 = -1; int pre = 0; int min = 0; int max = 0; for(uint i =0;i<N;++i) { if(Cands[i]==true) { if(C1 == -1) { C1 = D1 = i; } else if(C2 == -1) { C2 =D2 = i; min = max = C2 -C1; } else { if(i-pre<min) { C1 = pre; C2 = i; min = C2-C1; } else if(i- pre > max) { D1 = pre; D2 = i; max = D2 -D1; } } pre =i; } } return min != 0; } bool GetMinMax(uint L,uint U,int &C1,int &C2, int&D1,int &D2) { if(L<2) L=2; static uint const SIZE = 10000002; static bool Cands[SIZE]; const uint N = U-L +1; GetPrimeNumbers(L,U,Cands); if(GetMinMax(Cands,N,C1,C2,D1,D2)) { C1+=L; C2+=L; D1+=L; D2+=L; return true; } return false; } int main() { uint L,U; while(cin>>L>>U) { int C1,C2,D1,D2; if(GetMinMax(L,U,C1,C2,D1,D2)) { printf("%d,%d are closest, %d,%d are most distant.\n",C1,C2,D1,D2); } else { printf("There are no adjacent primes.\n"); } } return 0; }