考虑用筛法排除区间内所有合数,对余下的数(素数)更新答案。
http://poj.org/problem?id=2689
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 typedef __int64 LL; 6 const int maxn = 5e4; 7 const int maxm = 1e6 + 10; 8 LL prime[6000], k; 9 LL f[maxm], t; 10 bool vis[maxm]; 11 bool np[maxm]; 12 LL a, b; 13 14 void init(){ 15 memset(vis, 0, sizeof vis); 16 k = 0; 17 for(int i = 2; i < maxn; i++){ 18 if(!vis[i]) prime[k++] = (LL)i; 19 for(int j = i; j < maxn; j += i) vis[j] = 1; 20 } 21 } 22 23 void solve(){ 24 //[a, b] [0, b - a] 25 if(a == 1) ++a; 26 memset(np, 0, sizeof np); 27 for(LL i = 0; i < k; i++){ 28 LL tem = a % prime[i]; 29 LL j0 = tem == 0 ? a : a + prime[i] - tem; 30 tem = b % prime[i]; 31 LL j1 = tem == 0 ? b : b - tem; 32 if(j0 == prime[i]) j0 += prime[i]; 33 for(LL j = j0; j <= j1; j += prime[i]) np[j - a] = 1; 34 } 35 LL maxi = -1, mini = 0x3f3f3f3f; 36 LL a1, b1; 37 t = 0; 38 for(int i = 0; i <= b - a; i++) if(!np[i]) f[t++] = i; 39 for(int i = 0; i < t - 1; i++){ 40 int d = f[i + 1] - f[i]; 41 if(d > maxi) a1 = f[i] + a, maxi = d; 42 if(d < mini) b1 = f[i] + a, mini = d; 43 } 44 if(maxi != -1){ 45 printf("%I64d,%I64d are closest, %I64d,%I64d are most distant. ", b1, b1 + mini, a1, a1 + maxi); 46 }else puts("There are no adjacent primes."); 47 } 48 49 int main(){ 50 //freopen("in.txt", "r", stdin); 51 init(); 52 while(~scanf("%I64d%I64d", &a, &b)) solve(); 53 return 0; 54 }