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 }