一.欧几里德
欧几里德是用来求最大公约数的算法
其算法的中心思想为:
设a,b的最大公约数为c,则c一定也是a%b的最大公约数
证明方法很多,下面列出最简单的一个:
令 :a = xc; b = yc ; a = bk + r
(1) 证明 c 为 r 的约数
$r = a - b*k = xc - ykc = c(x - ky) $
故 c 为 r 的一个约数,证毕
(2) 证明 c 为 b和r的最大公约数
因 b = y ∗ c b = y*c b=y∗c
r = ( x − k y ) ∗ c r = (x - ky)*c r=(x−ky)∗c
故问题转化为 : 证明 y 和 (x - ky) 互质
我们可以使用反证法:
假设y 和 (x - ky)存在公因子 t
令 y = p t y = pt y=pt
x − k y = q t x - ky = qt x−ky=qt
则 $x = ky + qt = kpt + qt = (kp + q) * t $
则说明 t 也是 x,y的公因子
但是
由初始定义:
a = x ∗ c a = x*c a=x∗c
b = y ∗ c b = y*c b=y∗c
若x,y存在公因子t,则 c*t 才为 a,b的最大公因子,则与初始条件 c 为 a,b的最大公因子矛盾。
故假设不成立。
即 y 和 (x - ky) 互质
因为
b = yc
r = (x-ky)*c
故 c 为 b,r的最大公约数,证毕
设gcd(a,b)为a,b,的最大公约数,则
==> gcd(a,b) = gcd(b,r) = gcd(b,a%b)
代码:
int gcd(int a,int b){
if(b == 0) return a;
return gcd(b,a%b);
}
二.拓展欧几里德
已知一个问题:
已知a,b,c均为整数 问对于ax + by = c来说是否存在整数解,如果存在则求出任意一组整数解
此问题我第一次是见于HDU的校赛,不过只是需要求解是否存在(原题大概是问一个三元一次方程ax + by + cz = d,在a,b,c,d确定的情况下存在多少组解)
此题正解是背包,而我是通过移项枚举z的值,然后快速判断二元一次方程是否存在解来判断方案数量。
但当时没学拓欧,就各种乱搞WA了8次,最后YY出了一个快速判断的公式,终于AC。
后来才知道,其实跟拓欧有着很大的联系。
回到开始的问题:
(一)对于判断是否有整数解,其实很简单,就判断一下:
c % gcd(a,b) == 0 是否成立
其实这是很容易想通的,令:
r = g c d ( a , b ) r = gcd(a,b) r=gcd(a,b)
则无论如果改变x,y的大小,对于ax + by 每次改变的值一定是r的倍数,因为
(a+b) ,(a-b), a, b,a+2b,a - 2b…都是r的倍数
如果c 不是 r的倍数,则一定不存在整数解。
(二)至于某一组x,y的值:
则可以用拓展欧几里德来求解:
首先考虑特殊情况:
a ∗ 1 + b ∗ 0 = g c d ( a , b ) = a a*1 + b*0 = gcd(a,b) = a a∗1+b∗0=gcd(a,b)=