最大公约数
最大公约数
最大公约数即为 Greatest Common Divisor,常缩写为 gcd
在素数一节中,我们已经介绍了约数的概念。
一组数的公约数,是指同时是这组数中每一个数的约数的数。而最大公约数,则是指所有公约数里面最大的一个。
那么如何求最大公约数呢?我们先考虑两个数的情况。
两个数的
如果我们已知两个数 和 ,如何求出二者的最大公约数呢?
不妨设
我们发现如果 是 的约数,那么 就是二者的最大公约数。 下面讨论不能整除的情况,即 ,其中 。
我们通过证明可以得到 ,过程如下:
设 ,显然有 。设 ,则 由右边的式子可知 为整数,即 所以对于 的公约数,它也会是 的公约数。
反过来也需要证明
设 ,我们还是可以像之前一样得到以下式子 因为左边式子显然为整数,所以 也为整数,即 ,所以 的公约数也是 的公约数。
既然两式公约数都是相同的,那么最大公约数也会相同
所以得到式子
既然得到了 ,这里两个数的大小是不会增大的,那么我们也就得到了关于两个数的最大公约数的一个递归求法。
| int gcd(int a, int b) {
if (b == 0) return a;
return gcd(b, a % b);
}
|
递归至 b==0
(即上一步的 a%b==0
) 的情况再返回值即可。
如果两个数 和 满足 ,我们称 和 互质。
多个数的
那怎么求多个书的最大公约数呢?显然答案一定是每个数的约数,那么也一定是每相邻两个数的约数。我们采用归纳法,可以证明,每次取出两个数求出答案后再放回去,不会对所需要的答案造成影响。
最小公倍数
两个数的
首先我们介绍这样一个定理——算术基本定理:
每一个正整数都可以表示成若干整数的乘积,这种分解方式在忽略排列次序的条件下是唯一的。
用数学公式来表示就是
设 ,
我们发现,对于 和 的情况,二者的最大公约数等于
最小公倍数等于
由于
所以得到结论是
要求两个数的最小公倍数,先求出最大公约数即可。
多个数的
可以发现,当我们求出两个数的 时,求最小公倍数是 的复杂度。那么对于多个数,我们其实没有必要求一个共同的最大公约数再去处理,最直接的方法就是,当我们算出两个数的 ,或许在求多个数的 时候,我们将它放入序列对后面的数继续求解,那么,我们转换一下,直接将最小公倍数放入序列即可
EXGCD - 扩展欧几里得定理
目的:求 的一组可行解
证明
设
由欧几里得定理可知:
所以
又因为
所以
因为 ,所以
将 不断代入递归求解直至 GCD(最大公约数,下同)为 0
递归 x=1,y=0
回去求解。
1
2
3
4
5
6
7
8
9
10
11
12 | int Exgcd(int a, int b, int &x, int &y) {
if (!b) {
x = 1;
y = 0;
return a;
}
int d = Exgcd(b, a % b, x, y);
int t = x;
x = y;
y = t - (a / b) * y;
return d;
}
|
函数返回的值为 GCD,在这个过程中计算 即可
build本页面最近更新:,更新历史
edit发现错误?想一起完善? 在 GitHub 上编辑此页!
people本页面贡献者:
copyright本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用