【题目链接】
ybt 1207:求最大公约数问题
OpenJudge NOI 2.2 7592:求最大公约数问题
【题目考点】
1. 递归
2. 求最大公约数
- 辗转相减法
- 辗转相除法
【解题思路】
如果两个数字较小,可以用枚举法找最大公约数:取较小数字,从该数字开始从大到小遍历,取一个最大的能同时被m,n整除的数字。
但本题输入的数字达到
1
0
9
10^9
109,该方法不行。
可以使用以下两种方法:
1. 辗转相减法
也叫更相减损术,方法为:
- 如果两数相等,该数即为要求的最大公约数。
- 如果两数不等,用较大数减去较小数,得到的差替换较大的数
重复上述过程,直到得到最大公约数。
2. 辗转相除法
用较大数除以较小数,得到余数。
- 若余数为0,那么上一次除法中的除数就是最大公约数。
- 若余数不为0,那么下一次的除法为上一次除法中的除数除以余数。
重复这一过程,直到得到最大公约数 。
每种方法都可以用迭代或递归的写法来完成。
【题解代码】
解法1:辗转相减法
- 迭代
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a, b;
cin >> a >> b;
while(a != b)
{
if(a > b)
a = a-b;
else
b = b-a;
}
cout << a;
return 0;
}
- 递归
#include<bits/stdc++.h>
using namespace std;
int gcd(int a, int b)//求a与b的最大公约数
{
if(a == b)
return a;
else if(a > b)
return gcd(a-b, b);
else
return gcd(a, b-a);
}
int main()
{
int a, b;
cin >> a >> b;
cout << gcd(a, b);
return 0;
}
解法3:辗转相除法(效率最高)
- 迭代
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a, b, t;
cin >> a >> b;
while(b != 0)//余数为0时跳出
{
t = a % b;//求a除以b的余数
a = b;
b = t;
}
cout << a;//上一次除法中较小数为最大公约数
return 0;
}
- 递归
#include<bits/stdc++.h>
using namespace std;
int gcd(int a, int b)//求a与b的最大公约数
{
if(b == 0)//如果余数为0,结果为除数b
return a;
return gcd(b, a%b);//下次调用时,第一个参数为较大数除以较小数的余数
}
int main()
{
int a, b;
cin >> a >> b;
cout << gcd(a, b);
return 0;
}