今天看了HDOJ上的1019题,题目的核心在于求两个数的最小公倍数(lowest common multiple),我想既然看到了这个题目,就把相关求两个数最小公倍数和最大公约数(greatest common divisor)之类的东西总结一下吧,于是就有了这篇文章,文章中参考了部分网络上的资源,尤其是求最大公约数的欧几里德算法,感谢。
首先说明下求最大公约数的欧几里德算法,也叫辗转相除法,如下:
欧几里德算法(辗转相除法),用于计算两个整数a,b的最大公约数。
其计算原理依赖于下面的定理:
定理:gcd(a,b) = gcd(b,a mod b)
证明:a可以表示成a = kb + r,则r = a mod b
一方面,假设d是a,b的一个公约数,则有 d|a, d|b,而r = a - kb,因此d|r
因此d是(b,a mod b)的公约数
另一方面,假设d 是(b,a mod b)的公约数,则d | b , d |r ,但是a = kb + r
因此d也是(a,b)的公约数
因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证!
(注 x|y:y可以被x整除,即 y mod x == 0 )
因此,求a和b的最大公约数就相当于求 b和a%b的最大公约数,如此循环下去,直到a mod b为零为止,因为如果a mod b为零的话,就说明gcd(a,b) = b了,结束。可根据上述算法描述写出程序如下:(分为递归和非递归)
求两个数的最小公倍数可以如下计算:用两个数的乘积除以两个数的最大公约数就可以了.程序如下:
在杭电的1019题目中,题目的本意是要求一系列数的最小公倍数,其实这完全可以通过递归来达到要求,求一系列数的最大公约数的原理也是一样的,程序如下:
结.