一、最大公因数
1.概念
- 因数:整数a除以整数b(b≠0)的商正好是整数而没有余数,我们就说b是a的因数。
- 如1、2、3、6是6的因数。
- 公因数:给定若干个整数,如果存在一些数是它们共同的因数,那么这些共同的因数就叫做它们的公因数。
- 如1、2、3、4、6、12是24和36的公因数。
- 最大公因数:全部公因数中最大的那个,称为这些整数的最大公因数。
- 如12是24和36的最大公因数。
2.辗转相除法(欧几里得算法)
求解两个给定整数的最大公因数,我们常用辗转相除法(即欧几里得算法)。
①定义
假设有a、b,且a>b,a%b=r,则有gcd(a,b)=gcd(b,r)
注:其中%是取余数的意思;gcd为Greatest Common Divisor,最大公因数。
如:5%3=2;gcd(24,36)=12。
②证明
设a、b均为正整数,则gcd(a,b)=gcd(b,a%b)
比如说gcd(24,18)=gcd(18,6)=gcd(6,0)
众所周知:任意整数和0的公约数是该整数的所有约数;0和任何一个整数a的最大公约数都是a;因为0被所有非0整数整除,所以任意非零的整数都是0的约数
所以gcd(6,0)最大公约数为6,根据欧几里得算法,gcd(24,18)=gcd(6,0)=6
所以24与18的最大公约数为6
定理证明
证明:gcd(a,b)=gcd(b,a%b)成立
注:前言必看,证法一二选一个看即可(证法相同,角度不同)
前言:
假设a>b,(若a<b,会互换位置;即gcd(a,b)=gcd(b,a%b);比如gcd(18,24)=gcd(24,18))
不妨a÷b=q……r(其中q和r分别是a除以b得到的商和余数,不可否认a,b,q,r均为正整数)
∵a÷b=q……r
∴a=bq+r (①式)
r=a-bq (②式)
证法一:
假设d为a和b的一个公约数,记为(a,b)
则存在a=dm (★式)
b=dn (★★式) (不可否认m,n均为正整数)
由(②式)(★式)(★★式)得
r=a-bq=dm-dnq=d(m-nq)
可以看出d是r的约数,所以d既是a和b的公约数,也是b和r的公约数,所以(a,b)=(d,r)
即(a,b)=(b,a%b)
由于d的任意性,得a和b的公约数都是b和a%b的公约数
因此a和b的公约数与b和a%b的公约数全部相等,故其最大公约数也相等
即有gcd(a,b)=gcd(b,a%b)
证法二:
假设d为b和r的一个公约数,记为(b,r)
则存在b=dk (★式)
r=dw (★★式) (不可否认k,w均为正整数)
由(①式)(★式)(★★式)得
a=bq+r=dkq+dw=d(kq+w)
可以看出d是a的约数,所以d既是b和r的公约数,也是a和b的公约数,所以(d,r)=(a,b)
即(a,b)=(b,a%b)
由于d的任意性,得a和b的公约数都是b和a%b的公约数
因此a和b的公约数与b和a%b的公约数全部相等,故其最大公约数也相等
即有gcd(a,b)=gcd(b,a%b)
例子
根据证明,我们举三个例子来看一下
(25,14)=(14,11)=(11,3)=(3,2)=(2,1)=(1,0)
1和0的公约数为1;除了1以外,没有其他公约数的两个数互质;因此25与14互斥
(36,14)=(14,8)=(8,6)=(6,2)=(2,0)
2和0的公约数为1,2;所以36与14的公约数也为1,2;因此gcd(36,14)=gcd(2,0)=2
(144,216)=(216,144)=(144,72)=(72,0)
所以72的所有约数就是144和216的所有公约数;因此gcd(144,216)=gcd(72,0)=72
由上面例子可以发现,如果a<b,那么定理的结果就是将a和b互换;如果a>b,那么通过这个定理总可以将数据规模变小,并且变小得非常快。
代码实现(C/C++)
循环实现
int gcd(int a, int b) {
int tmp = 0;
while (tmp = a % b) {
a = b;
b = tmp;
}
return b;
}
递归实现
int gcd(int a, int b) {
if (b == 0) return a;
else return gcd(b, a % b);
}
递归式:gcd(a,b)=gcd(b,a%b)
递归边界:gcd(a,0)=a
递归实现更简洁写法
int gcd(int a, int b) {
return !b ? a : gcd(b, a % b);
}
二、最小公倍数 Least Common Multiple(LCM)
正整数a与b的最小公倍数是指a与b的所有公倍数中最小的那个公倍数,例如4和6的最小公倍数为12,3和9的最小公倍数为9.一般用lcm(a,b)来表示a和b的最小公倍数。
求解方法
最小公倍数的求解是在最大公约数的基础上进行。当得到a和b的最大公约数d之后,可以马上得到a和b的最小公倍数是ab/d。
证明
这个公式通过集合可以很好地理解。
由上图我们容易发现,a和b的最大公约数即集合a与集合b的交集,而最小公倍数为集合a与集合b的并集。要得到并集,由于ab会使公因子部分多计算一次,因此需要除掉一次公因子,于是得到了a和b的最小公倍数是ab/d。
由于ab在实际计算时有可能溢出,因此更恰当的写法是a/db。由于d是a和b的最大公约数,因此a/d一定可以整除。