原题传送:http://poj.org/problem?id=2689
求相连素数最小距离和最大距离。
由于n很大,但是U-L较小,所以筛素数时只筛到sqrt(n)就可以了,利用这个已经筛出的素数表把[U,L]之间的素数筛出来。
1 #include <stdio.h> 2 #include <math.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #define LL long long 6 #define N 50000 7 #define M 1000001 8 9 LL base[N], res[M]; 10 LL l, u, k; 11 bool isprime[N], isres[M]; 12 LL c1, c2, d1, d2; 13 14 void init() // 筛素数 15 { 16 LL i, j; 17 memset(isprime, false, sizeof isprime); 18 for(i = 2, k = 0; i < N; i ++) 19 { 20 if(!isprime[i]) 21 { 22 base[k ++] = i; 23 for(j = i << 1; j < N; j += i) 24 isprime[j] = true; 25 } 26 } 27 } 28 29 void solve() 30 { 31 LL i, j, cnt; 32 memset(isres, false, sizeof isres); 33 for(i = 0; i < k; i ++) 34 { 35 LL tmp = l / base[i]; // 快速定位 36 while(tmp * base[i] < l || tmp <= 1) 37 ++ tmp; 38 for(j = tmp * base[i]; j <= u; j += base[i]) 39 isres[j - l] = true; 40 } 41 if(l == 1) 42 isres[0] = true; 43 for(cnt = 0, i = 0; i <= u - l; i ++) 44 { 45 if(!isres[i]) 46 res[cnt ++] = i + l; 47 } 48 if(cnt <= 1) 49 puts("There are no adjacent primes."); 50 else 51 { 52 LL max = 0, min = 0x7fffffff; 53 for(i = 1; i < cnt; i ++) 54 { 55 if(res[i] - res[i - 1] < min) 56 { 57 min = res[i] - res[i - 1]; 58 c1 = res[i - 1]; 59 c2 = res[i]; 60 } 61 if(res[i] - res[i - 1] > max) 62 { 63 max = res[i] - res[i - 1]; 64 d1 = res[i - 1]; 65 d2 = res[i]; 66 } 67 } 68 printf("%I64d,%I64d are closest, %I64d,%I64d are most distant.\n", c1, c2, d1, d2); 69 } 70 } 71 72 int main() 73 { 74 init(); 75 while(scanf("%lld%lld", &l, &u) != EOF) 76 solve(); 77 return 0; 78 }