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 }
AC代码

猜你喜欢

转载自www.cnblogs.com/huyufeifei/p/9508797.html