用辗转相除法求最大公约数:反复把 (a, b) 换成 (b, a mod b),公因数集合始终不变而第二个数严格变小,b 归零时 a 就是答案。
OJ: roj
题目 ID: 1207
难度:普及-
标签:数论gcd辗转相除法python
创建: 2026-09-29 23:37
更新: 2026-10-05 05:32
题目描述
给定两个正整数
样例输入:6 9,样例输出:3。
思路
用辗转相除法:循环把
参考代码
Python 版:
python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-09-29 23:37
# update_at: 2026-09-29 23:41
import sys
def gcd(a: int, b: int) -> int:
"""返回 a 与 b 的最大公约数:反复把 (a, b) 换成 (b, a % b),b 归零时 a 就是答案。"""
while b:
a, b = b, a % b # 余数严格变小,所以循环次数是 O(log min(a, b))
return a
def solve() -> None:
"""读入一行里的两个正整数,输出它们的最大公约数。"""
a, b = map(int, sys.stdin.buffer.read().split())
print(gcd(a, b))
if __name__ == "__main__":
solve()C++ 版(同一算法):
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-10-05 05:32
* update_at: 2026-10-05 05:32
*/
#include <cstdio>
typedef long long ll;
// gcd:辗转相除,反复把 (a, b) 换成 (b, a % b),b 归零时 a 就是答案
ll gcd(ll a, ll b) {
while (b != 0) {
ll r = a % b; // 余数严格变小,循环次数为 O(log min(a, b))
a = b;
b = r;
}
return a;
}
int main() {
ll a, b;
if (scanf("%lld %lld", &a, &b) != 2) return 0;
printf("%lld\n", gcd(a, b));
return 0;
}