1.試除法判定質數 2.分解質因數 質數


數論的基礎知識

質數(又稱素數)的定義:質數是指在大於1的自然數中,除了1和它本身以外不再有其他因數的自然數。

還有其他因數的是合數

1既不是質數也不是合數

一:如何判斷一個數是不是質數:試除法。時間復雜度O(sqrt(n))

性質:如果d能整除n的話,d | n,那么n / d也能整除n,(n / d) | n

n的所有約數都是成對出現的,d和n / d

所以我們在枚舉的時候,可以只枚舉每一對中較小的那一個

所以我們只枚舉d <= (n / d)這樣的d,即d * d <= n,d <= sqrt(n)。時間復雜度一定為O(sqrt(n))

二:分解質因數:試除法。

小學知識,如何將一個數分解質因數,短除法

分解質因數用短除法,把一個數進行短除可以分解成若干個質數相乘

分解質因數要從最小的質數2開始除,直到沒有因數2再除以下一個質數3…直至除得的商也是質數為止。

如何用編程實現短除法

暴力做法

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 void divide(int n) {
 4     for (int i = 2; i <= n; i++) {
 5         if (n % i == 0) { //求i的次數。只要這行成立,i一定是質數
 6             int s = 0;
 7             while (n % i == 0) {
 8                 n /= i;
 9                 s++;
10             }
11             //結束后,s就是i的次數
12             cout << i << " " << s << endl;
13         }
14     }
15 }
16 int main() {
17     int n;
18     cin >> n;
19     while (n--) {
20         int x;
21         cin >> x;
22         divide(x);
23         cout << endl;
24     }
25     return 0;
26 }

這里有些細節,對一個數分解質因數,從思路上想,應該枚舉這個數所有的質因數,但是在第4行,是枚舉了n這個數所有的因數 

枚舉所有的因數,而不是枚舉所有的質因數,會不會錯了

其實是沒錯的,然后就是數論較難理解的數學知識部分了,為什么這樣不錯

  當枚舉到i的時候,就意味着已經把從2 ~ i - 1所有的n的質因子都除干凈了

  然后如果又n % i == 0成立的話,n是i的倍數,所以i當中也不包含任何2 ~ i - 1的質因子,所以i一定是個質數

這樣的做法時間復雜度O(n),然后想辦法進行優化

首先有個性質:任意一個正整數n最多只有一個質因數大於根號n

很容易用反證法證明,如果n這個數有兩個質因數大於根號n,那兩個大於根號n的數相乘就大於n了

所以我們可以先把所有小於等於根號n的質因子枚舉出來,這樣時間復雜度就是O(sqrt(n)),最后再找那一個可能存在的大於根號n的質因子

時間復雜度最好的是O(log n),最壞是O(sqrt(n))

 題目一:試除法判定質數

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 bool is_prime(int n) { //試除法
 4     if (n < 2) {
 5         return false;
 6     }   
 7     for (int i = 2; i <= n / i; i++) {
 8         if (n % i == 0) {
 9             return false;
10         }
11     }
12     return true;
13 }
14 int main() {
15     int n;
16     cin >> n;
17     while (n--) {
18         int x;
19         cin >> x;
20         if (is_prime(x)) {
21             cout << "Yes" << endl;
22         } else {
23             cout << "No" << endl;
24         }
25     }
26     return 0;
27 }

題目二:分解質因數

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 void divide(int n) {
 4     for (int i = 2; i <= n / i; i++) {
 5         if (n % i == 0) { //求i的次數。只要這行成立,i一定是質數
 6             int s = 0;
 7             while (n % i == 0) {
 8                 n /= i;
 9                 s++;
10             }
11             //結束后,s就是i的次數
12             cout << i << " " << s << endl;
13         }
14     }
15     if (n > 1) { //如果最后n還大於1,那么此時的n就是那個大於根號n的質因子
16         cout << n << " " << 1 << endl;
17     }
18 }
19 int main() {
20     int n;
21     cin >> n;
22     while (n--) {
23         int x;
24         cin >> x;
25         divide(x);
26         cout << endl;
27     }
28     return 0;
29 }

 


免責聲明!

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



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