DES:给出一个区间[L, U]。找出这个区间内相邻的距离最近的两个素数和距离最远的两个素数。其中1<=L<U<=2147483647 区间长度不超过1000000.

思路:因为给出的U的范围超出了int的最大。所以不能直接打出1-U的素数表。【我们知道。利用素数筛法时是把所有的合数都筛掉了。那么我们也想办法把L-U内的合数都筛掉就可以了。那么只要用sqrt(U)内的素数去筛掉L-U的合数就可以了。】只是大概理解。。。。。。。

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <string.h>
 4 #include <iostream>
 5 using namespace std;
 6 
 7 #define N 500000
 8 #define len 10000000
 9 #define inf 0x7fffffff
10 bool isprime[N+5];
11 long long prime[N], cnt;
12 bool res[len+5];
13 
14 void init() { // 筛选50000内的素数。要注意i比较大时 会容易超int的范围
15      long long i, j;
16      cnt = 0;
17      memset(isprime, true, sizeof(isprime));
18      for (i=2; i<=N; ++i) {
19         if (isprime[i]) {
20             prime[cnt++] = i;
21             if (i*i <= N) {
22                 for (j=i*i; j<=N; j+=i) {
23                     isprime[j] = false;
24                 }
25             }
26         }
27      }
28 }
29 
30 int main() {
31     long long L, U, i, j, k, minn, maxx, s, t;
32     init();
33     while(~scanf("%lld%lld", &L, &U)) {
34         memset(res, 0, sizeof(res));
35         for (i=0; i<cnt; ++i) {
36             s = (L-1)/prime[i]+1;  // s和t表示了当前范围里的数对这个素数的最小倍数和最大倍数。 比如说 区间[3, 9] 对素数2 的 s 和 t 应是 2, 4
37             t = U/prime[i];   // 由这个例子可以知道为什么 L-1 最后再+1。t就可以直接除。
38             for (j=s; j<=t; ++j) { // 筛选出区间内的素数
39                 if (j>1) { // 不知道为什么==1的时候也不算?????
40                     res[j*prime[i]-L] = true;
41                 }
42             }
43         }
44         k = -1, minn = inf, maxx = -1;
45         long long dis, m1, m2;
46         for (i=0; i<=U-L; ++i) { // 求解最优值
47             if (!res[i]) {
48                 if (k!=-1) {
49                     dis=i-k;  // 记录两个素数的最远距离。
50                     if (dis > maxx) {
51                         maxx = dis;
52                         m1 = i;
53                     }
54                     if (dis < minn) {
55                         minn = dis;
56                         m2 = i;
57                     }
58                 }
59                 if (i+L != 1) // 注意1 的时候特殊判断1不是素数。
60                     k=i;
61             }
62         }
63         if (maxx == -1)
64             printf("There are no adjacent primes.\n");
65         else printf("%lld,%lld are closest, %lld,%lld are most distant.\n", m2-minn+L, m2+L, m1-maxx+L, m1+L);
66     }
67     return 0;
68 }
View Code

代码可以理解。裸敲好像。。。还是有一点难度。明天再敲一遍。

posted on 2015-10-10 19:44  小小八  阅读(277)  评论(1编辑  收藏  举报