求两个数的最大公因数(辗转相除法)
举例
找9和6的最大公因数:
9÷6=1……3
6÷3=2
3就是9和6的最大公因数。
再如:30和80的最大公因数。
80÷30=2……20
30÷20=1……10
20÷10=2
10就是30和80的最大公因数。
简单点的思路就是:
(1).先用一个数保存要求两个数的余数,
(2).每次选取那两个数里面最小的一个去除以余数,
(3).直到余数为0;
具体讲就是(以9和6为例):
(1)用一个变量保存它们的余数:int x=9%6=3;
(2)选9和6里最小的去取余余数: 6%3=0;
(3)余数为0了,所以就结束,如果没有为0,还要继续去除,知道为0;
代码思路:
首先就是要考虑到这个是会一直做除法运算的,直到结果为0,自然就想到while(余数!=0),
然后while里面肯定是要更新参数的,因为第一次做取余的时候用的是9%6,下一次是6%余数,换句话说也就是将第一步里的将上一步的除数当作下一步的被除数,把上一步的余数当作下一步的除数,然后以此类推。
while(余数!=0)
{
int yushu=(大数a)%(小数b);
大数a=小数b;
小数b=余数;
}
代入数据分析:
a=9,b=6
yushu=a%b=3;
a=b=6; b=yushu=3;
判断(a%b=6%3==0)此时循环结束 返回上一步b的值就是最终的答案;
再比如:a=80,b=30;
余数=80%30=20;
a=b=30; b=yushu=20
判断(上一步的余数也其实就是判断b是不是为0,显然不是0,继续)
yushu=a%b=30%20=10;
a=b=20; b=yushu=10;
判断(b不为0)
余数=a%b=20%10=0;
a=b=10;b=yushu=0;
返回上一次的10
辗转相除的原理
如果我们要求8251与6105的最大公因数的话,假设8251是这个数x的a倍,再假设6105是x的b倍,那么2146=8251-6105,是x的(a-b)倍,也是x的倍数,而无论这几个数如何加减,甚至相乘,都还是最大公约数的倍数,我们就可以把求8251与6105的最大公约数简化成求2146和6105的最大公约数,再把求2146与6105的最大公约数简化为求3959(=6105-2146)与2146的最大公约数,如此相减往复几次后,会发现两个数变相等了37=37,这个数就是两个原来数的最大公因数。 举个例子9和69-6=3,保留6,36-3=3,保留3,3发现两数相等,为3所以最大公因数为3
9和6的最大公因数,我们知道是3。9是3的倍数,6是3的倍数,那3也一定是3的倍数。
30和80的公因数为m,30是m的倍数,80是m的倍数。80里有的两个30也肯定是m的倍数,剩下的20也会是m倍数。10也会是m的倍数。10=10=m。
代码如下
#include<bits/stdc++.h>
using namespace std;
int f(int a,int b)
{
int x=max(a,b);
int y=min(a,b);
int yushu;
while(y)
{
yushu=x%y;
x=y;
y=yushu;
}
return x;
}
int main()
{
int n,m;
cin>>n>>m;
cout<<f(n,m)<<endl;
return 0;
}