请编写程序,输入两个整数,计算并输出它们的最大公约数。
输入格式
两个整数
输出格式
最大公约数(正整数)
说明:两个整数可以是正数、零和负数,两个整数的位数都不到 20 位。最大公约数必须是正整数。
注:若两个整数都为 0,则最大公约数规定为 1。
输入样例1
25 -30
输出样例1
5
输入样例2
7 0
输出样例2
7
输入样例3
0 0
输出样例3
1
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
思路:
本题解中的思路是基于欧几里得算法(辗转相除法)来求最大公约数。下面介绍详细的计算过程。
欧几里得算法的基本原理如下:
假设有两个正整数 a 和 b,且 a>b,则有:
a = b * q + r
其中,q 表示商数,r 表示余数。根据这个等式,可以得到以下结论:
- 如果 a%b=0,则 b 就是 a,b 的最大公约数;
- 否则,将 b 替换为
a%b
,同时将 a 替换为原先的 b,然后继续进行辗转相除,直到余数为 0。
求 a,b 的最大公约数的具体实现如下:
- 输入两个整数 a 和 b。
- 将 a,b 中较小的值替换为 b,确保 b 不小于 a。
- 持续执行「辗转相除」操作,计算出当前的余数。如果余数为 0,则说明找到了 a,b 的最大公约数,即为 b 的值。
- 如果余数不为 0,则用 b 替换 a,用余数替换 b,进行下一轮迭代。
需要注意的是,如果 a 和 b 的任意一个数是 0,那么它们的最大公约数默认为 1。另外,在计算过程中,为了避免负数情况的干扰,应当对变量取绝对值。
伪代码:
输入:正整数 a 和 b;
输出:a, b 的最大公约数。
// 确保 b 不小于 a
if a < b then
交换 a 和 b 的值;
while b ≠ 0 do
r = a % b; // 计算余数
a = b;
b = r;
输出 a 作为结果。
代码:
#include <stdio.h>
#include <stdlib.h> // 引入 abs() 函数
int main() {
long long int a, b;
long long int gcd; // 定义长整型变量存储最大公约数
scanf("%lld %lld", &a, &b); // 输入两个整数
if (a == 0 && b == 0) { // 特判如果两个数都为 0,规定其最大公约数为 1
printf("1\n");
return 0; // 程序结束
}
// 交换 a 和 b 的位置,以保证 b 不小于 a。
if (a < b) {
long long int tmp = a;
a = b;
b = tmp;
}
// 使用辗转相除法计算最大公约数
while (b != 0) {
long long int r = llabs(a) % llabs(b); // 取绝对值,防止负数取模
a = b;
b = r; // 交换 a 和 b 的位置,进入下一轮迭代。
}
gcd = llabs(a); // 最终 a 即为最大公约数
printf("%lld\n", gcd);
return 0; // 程序结束
}