poj2689(素數區間篩法模板)


題目鏈接: http://poj.org/problem?id=2689

 

題意: 給出一個區間 [l, r] 求其中相鄰的距離最近和最遠的素數對 . 其中 1 <= l <  r <= 2,147,483,647, r - l <= 1e6 .

 

思路: 素數區間篩

要找到 [l, r] 中相鄰最近和最遠的素數對肯定是需要找出 [l, r] 內所有素數 . 但是無論是直接線性打表還是暴力都處理不了這么大的數據 .

可以先給 sqrt(r) 內的素數打個表, 再用 sqrt(r) 內的素數去篩選 [l, r] 內的合數, 然后再遍歷一次 [l, r], 記錄答案即可 .

 

代碼:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #define ll long long
 5 using namespace std;
 6 
 7 const int MAXN = 1e6 + 10;
 8 const int MAX = 1e5;
 9 int prime[MAX], tag[MAX], vis[MAXN], tot;
10 
11 void get_prime(void){
12     for(int i = 2; i < MAX; i++){
13         if(!tag[i]){
14             prime[tot++] = i;
15             for(int j = 2; j * i < MAX; j++){
16                 tag[j * i] = 1;
17             }
18         }
19     }
20 }
21 
22 ll Max(ll a, ll b){
23     return a > b ? a : b;
24 }
25 
26 int main(void){
27     get_prime();
28     ll l, r;
29     while(~scanf("%lld%lld", &l, &r)){
30         memset(vis, 0, sizeof(vis));
31         for(int i = 0; i < tot; i++){
32             ll a = (l + prime[i] - 1) / prime[i];
33             ll b = r / prime[i];
34             for(int j = Max(2, a); j <= b; j++){ // 篩[l, r]內的合數
35                 vis[prime[i] * j - l] = 1; //減個l方便標記,輸出答案時加回去即可
36             }
37         }
38         if(l == 1) vis[0] = 1; // 注意這個1並不是素數
39         ll cnt = -1, sol1 = MAXN, sol2 = 0, x1, y1, x2, y2;
40         for(int i = 0; i <= r - l; i++){
41             if(vis[i] == 0){
42                 if(cnt != -1){
43                     if(sol1 > i - cnt){
44                         x1 = cnt;
45                         y1 = i;
46                         sol1 = i - cnt;
47                     }
48                     if(sol2 < i - cnt){
49                         x2 = cnt;
50                         y2 = i;
51                         sol2 = i - cnt;
52                     }
53                 }
54                 cnt = i;
55             }
56         }
57         if(sol2 == 0) puts("There are no adjacent primes.");
58         else printf("%lld,%lld are closest, %lld,%lld are most distant.\n", x1 + l, y1 + l, x2 + l, y2 + l);
59     }
60     return 0;
61 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM