最大公约数问题
正整数a和b的最大公约数是指正整数a和b所有公约数中最大的那个公约数。
一般用gcd(a,b)来表示a和b的最大公约数,而求解最大公约数常用欧几里得算法(辗转相除法)。
欧几里得算法
证明:有a=kb+r,其中k和r分别为a除以b得到的商和余数。
则有 r=a-kb成立。
设d是a和b的一个公约数。
那么可得r%d=a%d-kb%d,即可得d也是r的一个公约数。
又因为r=a%b,则d为b和a%b的一个公约数
由d的任意性可得,a和b的公约数都是b和a%b的公约数。
同理也可证b和a%b的公约数都是a和b的公约数。
因此a和b的公约数与b和a%b的公约数全部相等。
故其最大公约数也相等。即有gcd(a,b)=gcd(b,a%b)。
算法思路
通过以上定理可以发现,欧几里得算法可以很好的缩小数据规模,并且减小的非常快,总所周知:0和任意整数a的最大公约数都是a,这个可以当做递归边界!
所以我们可以得到:
- 递归式:gcd(a,b)=gcd(b,a%b)
- 递归边界:gcd(a,0)=a
【codeup 1818】最大公约数
题目描述
输入两个正整数,求其最大公约数
输入
测试数据有多组,每组输入两个正整数。
输出
对于每组输入,请输出最大公约数。
样例输入
49 14
样例输出
7
实现代码
#include<stdio.h>
int gcd(int a,int b)
{
if(b==0) return a;
else return gcd(b,a%b);
}
int main()
{
int a,b;
while(scanf("%d%d",&a,&b)!=EOF)//检测到结束符的时候才结束循环
{
printf("%d\n",gcd(a,b));
}
return 0;
}
最小公倍数问题
在欧几里得算法求解最大公约数的基础上,我们很快的得到两个数的最小公倍数。
实现思路
给定两个整数a和b,假定其最大公约数为d。
则a=d×a1,b=d×b1。
由于d为重复部分,那么我们便可得两数最小公倍数为a* b/d。但考虑到溢出问题,一般我们把他表示成a/d*b的形式
解决此类问题时,需要先实现求解最大公约数,之后求解最小公倍数便简单多了!