欧几里得算法计算 GCD 和 LCM 引入 例题(B4025 最大公约数) 定义两个正整数的最大公约数 gcd(a,b)gcd(a,b) 为最大的正整数 d,使得 d 可以同时整除 a 和 b。
例如,gcd(9,12)=3gcd(9,12)=3,因为 9÷3 和 12÷3 的余数是 0,而无法找到一个比 3 更大的正整数满足要求。
现在给定两个正整数 a,b,要求出 gcd(a,b)
暴力解法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <iostream> #include <algorithm> using namespace std;int main () { long long a,b,m=0 ; cin >> a >> b; for (int i=min (a,b); i >= 1 ; i--) { if (a % i != 0 || b % i != 0 ) continue ; m = i; break ; } cout << m; return 0 ; }
OK,直接TLE得50分。这个时候就需要用到欧几里得算法来解题。
欧几里得算法讲解 GCD 欧几里得算法的时间复杂度是 O(log(min(a,b))),比暴力枚举要快得多。以下是使用欧几里得算法的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <iostream> using namespace std;int main () { long long a, b; cin >> a >> b; while (b != 0 ) { long long temp = b; b = a % b; a = temp; } cout << a; return 0 ; }
这个实现通过不断将 a 取模 b,并交换 a 和 b,直到 b 为零时,a 就是最大公约数。这样可以大大提高效率。
PS:在欧几里得算法中,也不需要提前比较 a 和 b 的大小,因为算法本身就会完成这一步骤。
LCM 对于两个正整数 (a) 和 (b),它们的最小公倍数可以通过以下公式计算:
$$ {lcm}(a, b) = \frac{|a \times b|}{\text{gcd}(a, b)} $$
以下是计算gcd和lcm的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <iostream> using namespace std;long long gcd (long long a, long long b) { while (b != 0 ) { long long temp = b; b = a % b; a = temp; } return a; } long long lcm (long long a, long long b) { return (a / gcd (a, b)) * b; } int main () { long long a, b; cin >> a >> b; cout << "GCD: " << gcd (a, b) << endl; cout << "LCM: " << lcm (a, b) << endl; return 0 ; }
通过先计算出两数的最大公约数,再利用公式计算出最小公倍数,可以高效地求出结果。