poj 2689(素数)
这道题是学习素数筛法的经典,应用到了区间筛素数。具体思路是先筛出1到sqrt(2147483647)之间的所有素数,然后再通过已经晒好素数筛出给定区间的素数。
PS:如果用的int存low,high(输入)。注意high=2147483647.加1就变成负数了。
1 // File Name: 2689.cpp 2 // Author: Missa_Chen 3 // Created Time: 2013年05月28日 星期二 23时16分51秒 4 5 #include<iostream> 6 #include<string> 7 #include<algorithm> 8 #include<cstdio> 9 #include<cstring> 10 #include<cmath> 11 #include<queue> 12 #include<map> 13 #include<stack> 14 #include<set> 15 #include<cstdlib> 16 17 using namespace std; 18 19 #define LL long long 20 const int inf = 0x3f3f3f3f; 21 const int maxn = 1e6 + 5; 22 int low, high; 23 int prim[maxn], p[maxn], pn; 24 void prime() 25 { 26 pn = 0; 27 memset(p,0,sizeof(p)); 28 p[0] = p[1] = 1; 29 for (int i = 2; i < maxn; ++i) 30 { 31 if (p[i]) continue; 32 for (int j = i << 1; j < maxn; j += i) 33 p[j] = 1; 34 prim[pn++] = i; 35 } 36 } 37 void prime2() 38 { 39 for (int i = 0; i < maxn; ++i) p[i] = 1; 40 if (low == 1) 41 p[0] = 0; 42 for (int i = 0; i < pn; ++i) 43 { 44 if (prim[i] *(LL)prim[i] > high) break; 45 LL st = low / prim[i]; 46 for (LL j = st * prim[i]; j <= high; j += prim[i]) 47 { 48 if (j < low) continue; 49 if (j == prim[i]) continue; 50 p[j - low] = 0; 51 } 52 } 53 int min_ans = inf, max_ans = -1, pre = -1; 54 int res1,res2,res3,res4; 55 for (int i = low; i <= high; ++i) 56 { 57 if (i < 0) break;//坑爹。以后还是用LL吧 58 if (p[i - low]) 59 { 60 if (pre == -1) 61 pre = i; 62 else 63 { 64 if (i - pre < min_ans) 65 { 66 min_ans = i - pre; 67 res1 = pre; 68 res2 = i; 69 } 70 if (i - pre > max_ans) 71 { 72 max_ans = i - pre; 73 res3 = pre; 74 res4 = i; 75 } 76 pre = i; 77 } 78 } 79 } 80 if (max_ans == -1) 81 { 82 printf("There are no adjacent primes.\n"); 83 } 84 else 85 { 86 printf("%d,%d are closest, %d,%d are most distant.\n",res1,res2,res3,res4); 87 } 88 89 } 90 int main() 91 { 92 prime(); 93 while (~scanf("%d%d",&low,&high)) 94 { 95 prime2(); 96 } 97 return 0; 98 }