题目描述 Description
求两个数A和B的最大公约数。 1<=A,B<=2^31-1
输入描述 Input Description
两个整数A和B
输出描述 Output Description
最大公约数gcd(A,B)
样例输入 Sample Input
8 12
样例输出 Sample Output
4
数据范围及提示 Data Size & Hint
本题仍然是知识题~~
所用知识:辗转相除法(欧几里得算法);
辗转相除法是求两个正整数最大公约数的算法,首先,不加证明地给出它的递归定义:
gcd(a,b)=
a (b=0);
gcd(b,a mod b) (b<>0);
下面给出它的证明:
首先这涉及到带余除法:存在q使得a-qb=r,则r定义为a mod b。
那么,要证明gcd(a,b)=gcd(b,a mod b),只需要证明(a,b)和(b,r)有相同的公因子。
设公因子集合中元素d,则d能整除a和b(以后将用“|”)代替。
a-qb=r先放在这儿看着。
若a|b&a|c(这样可以认为b=n*a;c=m*a),那么对于多项式xb+yc(它就变成了a(n*x+m*b)),无论x,y为何值,a|xb+yc。
那么回来看,对于d|a&d|b,则d|xa-yb,即d|a-qb,即d|r;
………………
那么(a,b)和(b,r)就有相同的公因子了,然后就完了~~~
具体的欧几里得算法可以用递归或递推实现,由于递归层数不会太多,所以笔者使用递归式求解此题。
算法描述:输入,调用函数计算gcd(a,b),输出gcd(a,b)。
Program gcdpro;
Var
x:longint;
y:longint;
Function gcd(aa,bb:longint):longint;
var aaa:longint;
begin
if aa<bb then begin aaa:=aa;aa:=bb;bb:=aaa;end;
if bb=0 then exit(aa);
gcd:=gcd(bb,aa mod bb);
end;
Begin
readln(x,y);
writeln(gcd(x,y));
End.