【NYOJ-187】快速查找素數—— 枚舉法、篩選法、打表法


快速查找素數

時間限制: 1000 ms  |  內存限制:65535 KB
難度: 3
 
描述
現在給你一個正整數N,要你快速的找出在2.....N這些數里面所有的素數。
輸入
給出一個正整數數N(N<=2000000)
但N為0時結束程序。
測試數據不超過100組
輸出
將2~N范圍內所有的素數輸出。兩個數之間用空格隔開
樣例輸入
5
10
11
0
樣例輸出
    2 3 5
      2 3 5 7
      2 3 5 7 11
【分析】
  • 枚舉法:
 1 //根據概念判斷:
 2 //如果一個正整數只有兩個因子, 1和p,則稱p為素數.
 3 //代碼:
 4 bool isPrime(int n)
 5 {
 6     if(n < 2) return false;
 7 
 8     for(int i = 2; i < n; ++i)
 9         if(n%i == 0) return false;
10     return true;
11 }
12 //時間復雜度O(n)
 1 //改進, 去掉偶數的判斷
 2 //代碼:
 3 bool isPrime(int n)
 4 {
 5     if(n < 2) return false;
 6     if(n == 2) return true;
 7     if(n % 2 == 0) return false;
 8     for(int i = 3; i < n; i += 2)
 9         if(n%i == 0) return false;
10     return true;
11 }
12 //時間復雜度O(n/2), 速度提高一倍.
 1 /進一步減少判斷的范圍
 2 //定理: 如果n不是素數, 則n有滿足1<d<=sqrt(n)的一個因子d.
 3 //證明: 如果n不是素數, 則由定義n有一個因子d滿足1<d<n.
 4 //如果d大於sqrt(n), 則n/d是滿足1<n/d<=sqrt(n)的一個因子.
 5 //代碼:
 6 bool isPrime(int n)
 7 {
 8     if(n < 2) return false;
 9     if(n == 2) return true;
10     if(n % 2 == 0) return false;
11     for(int i = 3; i*i <= n; i += 2)
12         if(n%i == 0) return false;
13     return true;
14 }
15 //時間復雜度O(sqrt(n)/2), 速度提高O((n-sqrt(n))/2).
  • 篩選法
  顯然以上的枚舉法,不管如何改進都是不能AC的,所以枚舉法肯定是行不通的。
  用篩法求素數的基本思想是:把從1開始的、某一范圍內的正整數從小到大順序排列, 1不是素數,首先把它篩掉。剩下的數中選擇最小的數是素數,然后去掉它的倍數。依次類推,直到篩子為空時結束。如有:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 
  1不是素數,去掉。剩下的數中2最小,是素數,去掉2的倍數,余下的數是:
  3 5 7 9 11 13 15 17 19 21 23 25 27 29
  剩下的數中3最小,是素數,去掉3的倍數,如此下去直到所有的數都被篩完,求出的素數為:
  2 3 5 7 11 13 17 19 23 29
 1 //篩法判斷素數 一
 2 #include<cstdio>
 3 #define MAXN 2000001
 4 int a[MAXN],i,j;
 5 int main(){
 6     int m;
 7     //篩選出二百萬內的所有素數
 8     for(i = 2;i <= 2000000;i++){
 9         if(a[i]==0)
10             //利用數組的下標,將i的倍數全部篩掉
11             for(j = i + i;j <= 2000000;j += i)
12                 a[j] = 1;
13     }
14     while(scanf("%d",&m) && m!=0){
15         //從數組中依據下標取出[2,m]內的所有素數
16         for(i = 2;i <= m;i++){
17             if(a[i] == 0){
18                 printf("%d ",i);
19             }
20         }
21         printf("\n");
22     }
23     return 0;
24 }
 1 //篩法判斷素數 二
 2 #include<cstdio>
 3 #define MAXN 2000001
 4 int a[MAXN],i,j;
 5 int main(){
 6     int m;
 7     while(scanf("%d",&m) == 1 && m!=0){
 8         //m有多大,數組用多大
 9         for(i = 2;i <= m;i++)
10             a[i] =i;
11         //m/2縮小范圍
12         for(i = 2;i <= m/2;i++){
13             if(a[i] != 0){
14                 for(j=i+i;j <= m;j += i){
15                     //將i的倍數全部篩掉
16                     a[j] = 0;
17                 }
18             }
19         }
20         for(i = 2;i <= m;i++){
21             if(a[i] != 0) printf("%d\n",a[i]);
22         }
23     //    printf("\n");
24     }
25     return 0;
26 }
  • 素數打表法

  正在研究..... 先挖個坑。

  順便吐槽NYOJ的服務器。還能再爛么?


免責聲明!

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



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