由于区间的右端点非常大(INT_MAX),而区间长度相对小(100W),所以考虑区间筛法,左端点为1的情况需要特判一下。
1 #include <cstring> 2 #include <cstdio> 3 #include <cmath> 4 using namespace std; 5 6 typedef long long ll; 7 const int MAX = 9999999; 8 const int MIN = -1; 9 const int N = 50000; 10 const int M = 5000; 11 const int K = 1000001; 12 bool visit[N]; 13 int prime[M]; 14 bool big_visit[K]; 15 int big_prime[N]; 16 int pn; 17 18 void sieve( int n ) 19 { 20 int r = sqrt( n + 0.5 ); 21 memset( visit, 0, sizeof(visit) ); 22 visit[0] = visit[1] = 1; 23 for ( int i = 2; i <= r; i++ ) 24 { 25 if ( !visit[i] ) 26 { 27 for ( int j = i * i; j <= n; j += i ) 28 { 29 visit[j] = 1; 30 } 31 } 32 } 33 } 34 35 void get_prime( int n ) 36 { 37 sieve(n); 38 pn = 0; 39 for ( int i = 0; i <= n; i++ ) 40 { 41 if ( !visit[i] ) 42 { 43 prime[pn++] = i; 44 } 45 } 46 } 47 48 int main () 49 { 50 get_prime( N - 1 ); 51 int l, u; 52 while ( scanf("%d%d", &l, &u) != EOF ) 53 { 54 memset( big_visit, 0, sizeof(big_visit) ); 55 if ( l == 1 ) big_visit[0] = 1; 56 int bound = sqrt( u + 0.5 ); 57 for ( int i = 0; prime[i] <= bound; i++ ) 58 { 59 int r = ( ( ll ) l + prime[i] - 1 ) / prime[i]; 60 if ( r < 2 ) r = 2; 61 for ( ll j = ( ll ) r * prime[i]; j <= ( ll ) u; j += prime[i] ) 62 { 63 big_visit[j - l] = 1; 64 } 65 } 66 int cnt = 0; 67 for ( int i = 0; i <= u - l; i++ ) 68 { 69 if ( !big_visit[i] ) 70 { 71 big_prime[cnt++] = i; 72 } 73 } 74 if ( cnt == 1 ) 75 { 76 printf("There are no adjacent primes. "); 77 continue; 78 } 79 int minn = MAX, maxn = MIN, pma = -1, pmi = -1; 80 for ( int i = 0; i < cnt - 1; i++ ) 81 { 82 int d = big_prime[i + 1] - big_prime[i]; 83 if ( d > maxn ) 84 { 85 maxn = d; 86 pma = i; 87 } 88 if ( d < minn ) 89 { 90 minn = d; 91 pmi = i; 92 } 93 } 94 int o1 = big_prime[pmi] + l, o2 = big_prime[pmi + 1] + l; 95 int o3 = big_prime[pma] + l, o4 = big_prime[pma + 1] + l; 96 printf("%d,%d are closest, %d,%d are most distant. ", o1, o2, o3, o4); 97 } 98 return 0; 99 }