数学问题——最大公约数与最小公倍数
1. 最大公约数
正整数 a 与 b 的最大公约数是指 a 与 b 的所有公约数中最大的那个公约数,一般用 gcd(a,b) 来表示 a 和 b 的最大公约数,而求解最大公约数常用欧几里得算法(即辗转相除法)。
欧几里得算法基于下面这个定理:
设 a、b 均为正整数,则 gcd(a,b) = gcd(b,a%b) 。
利用这个定理可以很快得到结果,只是还需要一个东西:递归边界。众所周知:0 和任意一个整数 a 的最大公约数都是 a(注意:不是0),这个结论可以作为递归边界。那么递归的两个关键已经得到:
-
- 递归式: gcd(a,b) = gcd(b,a%b) 。
- 递归边界:gcd(a,0) = a 。
于是可以得到下面的求解最大公约数的代码:
1 // 欧几里得算法求最大公约数 2 int gcd(int a, int b) { 3 if(b == 0) return a; 4 else return gcd(b, a%b); 5 }
下面来看一个例题。
【codeup 1818】最大公约数
题目:输入两个正整数,求其最大公约数。
思路:直接使用上面的代码即可。
代码如下:
1 /* 2 最大公约数 3 */ 4 5 #include <cstdio> 6 #include <cstring> 7 #include <algorithm> 8 #include <cmath> 9 #include <cstdlib> 10 #include <ctime> 11 using namespace std; 12 13 // 欧几里得算法求最大公约数 14 int gcd(int a, int b) { 15 if(b == 0) return a; 16 else return gcd(b, a%b); 17 } 18 19 int main() { 20 int a, b; 21 while(scanf("%d%d", &a, &b) != EOF) { 22 printf("%d\n", gcd(a, b)); 23 } 24 25 return 0; 26 }
2. 最小公倍数
正整数 a 与 b 的最小公倍数是指 a 与 b 的所有公倍数中最小的那个公倍数。一般用 lcm(a,b) 来表示 a 和 b 的最小公倍数。
最小公倍数的求解在最大公约数的基础上进行的。当得到 a 和 b 的最大公约数 d 之后,可以马上得到 a 和 b 的最小公倍数为 ab / d 。
由于 ab 在实际计算时有可能溢出,因此更恰当的写法是 a / d * b 。
主要代码如下:
1 // 求最小公倍数 2 int lcm(int a, int b) { 3 int d = gcd(a, b); 4 return a / d * b; 5 }