1. 题目背景与需求分析
这道GESP五级真题考察的是数论中的最大公因数(GCD)计算问题。题目给出两个正整数a和b,要求计算它们的最大公因数。虽然题目本身看似基础,但结合五级考试的要求,我们需要考虑算法效率和边界条件处理。
在C++中计算GCD通常有三种主流方法:
- 暴力枚举法:从较小数开始向下遍历,找到第一个能同时整除两数的数
- 辗转相除法(欧几里得算法):利用gcd(a,b)=gcd(b,a mod b)的性质递归计算
- 更相减损术:中国古代算法,通过相减实现
实际工程中推荐使用辗转相除法,其时间复杂度为O(log min(a,b)),远优于暴力法的O(n)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算法选择与实现细节
2.1 辗转相除法实现
cpp复制int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
这个简洁的递归实现有几个关键点需要注意:
- 递归终止条件是b=0,此时a就是GCD
- a % b保证了每次递归时参数都在减小
- 不需要考虑a和b的大小关系,因为gcd(a,b)=gcd(b,a)
2.2 迭代版本实现
对于担心递归栈溢出的情况,可以改写为迭代版本:
cpp复制int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
2.3 边界条件处理
实际编程时需要特别注意:
- 输入为0的情况:gcd(a,0)=a
- 负数处理:可以先取绝对值
- 大数运算:当a和b很大时,要考虑使用long long类型
3. 性能优化与剪枝策略
虽然辗转相除法已经很高效,但在竞赛环境下还可以进一步优化:
3.1 位运算优化
利用位运算可以加速模运算:
cpp复制int gcd(int a, int b) {
if (a == b) return a;
if ((a & 1) == 0 && (b & 1) == 0)
return gcd(a >> 1, b >
