牛客网NC22215:最大公约数
问题描述
最大公约数(GCD)是两个或多个整数共有约数中最大的一个。给定两个正整数A和B,求它们的最大公约数。
问题链接
输入输出说明
输入格式:
- 一行,包含两个正整数A和B(1 ≤ A,B ≤ 10^9)
输出格式:
- 一行,包含一个正整数,表示A和B的最大公约数
示例:
输入:4 6
输出:2
算法思路
本题采用欧几里得算法(辗转相除法)求解最大公约数。该算法基于一个重要性质:两个数的最大公约数等于其中较小的数与两数相除余数的最大公约数。
算法步骤:
- 如果b等于0,则a就是最大公约数
- 否则,将a除以b,得到余数r
- 将b赋给a,将r赋给b
- 返回步骤1,继续迭代
代码实现
#include<bits/stdc++.h>
using namespace std;
int main(){
int a, b, c;
cin >> a >> b;
while(b > 0){
c = a % b; // 计算a除以b的余数
a = b; // 将b赋值给a
b = c; // 将余数赋值给b
}
cout << a << endl; // 当b为0时,a即为最大公约数
}
举例
初始值:a=48, b=18
循环过程:
- c = 48%18 = 12 → a=18, b=12
- c = 18%12 = 6 → a=12, b=6
- c = 12%6 = 0 → a=6, b=0(循环终止)
输出结果:6
算法分析
- 时间复杂度:O(log(min(a,b))),欧几里得算法的时间复杂度与输入数字的对数相关
- 空间复杂度:O(1),只使用了常数个变量
扩展知识
-
最小公倍数(LCM):两个数A和B的最小公倍数可以通过公式
LCM(A,B) = (A*B)/GCD(A,B)
计算。 -
辗转相除法的证明:
设gcd(a,b)表示a和b的最大公约数。
假设d是a和b的一个公约数,则a=kd,b=md,其中k和m是整数。
令a=qb+r,其中q是整数,r是余数。
则r=a-qb=kd-qmd=(k-qm)d,说明d也是r的约数。
因此,gcd(a,b) = gcd(b,r)。
欧几里得算法简洁高效,是求解最大公约数的经典方法,在数论、密码学等领域有广泛应用。