poj2689 Prime Distance
题意:求[a, b]之间差最大/小的相邻素数。
0 < a, b < 2^32, 0 < b - a <= 1e6
首先发现a,b很大,以至于无法求出素数来。
然后就考虑退而求次,求出sqrt(b)以内的素数。
发现可以枚举[a, b]之间的数,还开的下一个vis数组。
然后考虑筛去所有合数。
用sqrt(b)以内的素数筛合数即可。
有两个点要注意:
1,b可能等于2147483647,故for循环里面要写成 i <= b && i > 0
2,注意1不是质数,所以a == 1时vis[0] = 1
1 #include <cstring> 2 #include <cstdio> 3 typedef long long LL; 4 const int N = 2000010; 5 LL INF = 2147483647; 6 7 int a, b, top, p[N]; 8 bool vis[N]; 9 10 inline void solve() { 11 memset(vis, 0, (b - a + 1) * sizeof(bool)); 12 for(int i = 1; i <= top && p[i] * p[i] <= b; i++) { 13 int j = (a / p[i]) * p[i]; 14 if(j < a) { 15 j += p[i]; 16 } 17 if(j == p[i]) { 18 j += p[i]; 19 } 20 for(; j <= b && j > 0; j += p[i]) { 21 vis[j - a] = 1; 22 } 23 } 24 if(a == 1) { 25 vis[0] = 1; 26 } 27 28 int last = 0; 29 int c = 0, d = 0; 30 for(int i = a; i <= b && i > 0; i++) { 31 if(vis[i - a]) { 32 continue; 33 } 34 if(!d) { 35 d = i; 36 } 37 else if(!c) { 38 c = d; 39 d = i; 40 last = d; 41 } 42 else { 43 if(i - last < d - c) { 44 c = last; 45 d = i; 46 } 47 last = i; 48 } 49 } 50 if(!c) { 51 puts("There are no adjacent primes."); 52 return; 53 } 54 printf("%d,%d are closest, ", c, d); 55 last = c = d = 0; 56 for(int i = a; i <= b && i > 0; i++) { 57 if(vis[i - a]) { 58 continue; 59 } 60 if(!d) { 61 d = i; 62 } 63 else if(!c) { 64 c = d; 65 d = i; 66 last = d; 67 } 68 else { 69 if(i - last > d - c) { 70 c = last; 71 d = i; 72 } 73 last = i; 74 } 75 } 76 printf("%d,%d are most distant.\n", c, d); 77 return; 78 } 79 80 inline void getp() { 81 for(int i = 2; 1ll * i * i <= INF; i++) { 82 if(!vis[i]) { 83 p[++top] = i; 84 } 85 for(int j = 1; j <= top && 1ll * i * p[j] * i * p[j] <= INF; j++) { 86 vis[i * p[j]] = 1; 87 if(i % p[j] == 0) { 88 break; 89 } 90 } 91 } 92 return; 93 } 94 95 int main() { 96 getp(); 97 while(scanf("%d%d", &a, &b) != EOF) { 98 solve(); 99 } 100 101 return 0; 102 }