1. 题目背景与需求解析
这道GESP C++一级考试题目"交朋友"看似简单,却蕴含了编程初学者需要掌握的多个核心概念。题目描述了一个生活化的场景:Alice要在班上三位同学中寻找与自己身高最接近的朋友。如果存在多个相同差距的同学,则选择其中最矮的一位。
这个题目主要考察以下几个编程基础能力:
- 变量的定义与使用
- 基本的输入输出操作
- 条件判断语句的应用
- 绝对值的计算与比较
- 简单算法的设计与实现
对于初学者而言,这道题的价值在于它把抽象的编程概念具象化为一个容易理解的现实场景。通过解决这个问题,学生能够直观地理解如何用代码解决实际问题。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 解题思路详解
2.1 基础解法分析
最直观的解法是分别计算Alice与其他三位同学的身高差,然后进行比较。具体步骤如下:
- 定义四个变量存储四个人的身高
- 计算Alice(h1)与h2、h3、h4的绝对差值
- 初始化最小差值为h1与h2的差值
- 依次比较h3和h4的差值
- 如果差值更小,更新最小差值和答案
- 如果差值相同,比较身高,保留较矮的
- 输出最终结果
这种方法的优点是逻辑清晰,易于理解,适合编程初学者。它直接反映了我们人工解决问题的思考过程。
2.2 优化解法思路
更进阶的解法是使用数组和循环结构,这体现了更好的编程实践:
- 使用数组存储四个身高值
- 初始化最小差值为一个足够大的数(如100)
- 使用循环遍历其他三位同学
- 在循环中计算当前差值
- 比较并更新最小差值和答案
- 输出结果
这种方法减少了重复代码,更易于扩展。如果同学数量增加,只需调整循环次数即可,而不需要修改核心逻辑。
3. 代码实现与解析
3.1 基础实现代码
cpp复制#include<bits/stdc++.h>
using namespace std;
int h1, h2, h3, h4;
int main() {
cin >> h1 >> h2 >> h3 >> h4;
int c12 = abs(h1 - h2);
int c13 = abs(h1 - h3);
int c14 = abs(h1 - h4);
int minc = c12;
int ans = h2;
if (c13 < minc) {
minc = c13;
ans = h3;
} else if (c13 == minc && h3 < ans) {
ans = h3;
}
if (c14 < minc) {
minc = c14;
ans = h4;
} else if (c14 == minc && h4 < ans) {
ans = h4;
}
cout << ans << endl;
return 0;
}
代码解析:
- 使用
abs()函数计算绝对值,比手动判断更简洁 - 初始化时将h2设为第一个候选
- 分别比较h3和h4的情况
- 在差值相同时,额外比较身高
- 最终输出结果
3.2 优化实现代码
cpp复制#include<bits/stdc++.h>
using namespace std;
int h[5];
int main() {
for (int i = 1; i <= 4; i++) {
cin >> h[i];
}
int minc = 100;
int ans = h[2];
for (int i = 2; i <= 4; i++) {
int c = abs(h[i] - h[1]);
if (c < minc) {
minc = c;
ans = h[i];
} else if (c == minc && h[i] < ans) {
ans = h[i];
}
}
cout << ans;
return 0;
}
代码优化点:
- 使用数组存储身高,更易于管理
- 使用循环结构减少重复代码
- 初始minc设为100,确保第一次比较必定更新
- 循环从i=2开始,直接跳过Alice自己
4. 关键知识点详解
4.1 绝对值计算
在本题中,计算身高差需要使用绝对值,因为身高差的方向不重要。C++中有两种计算绝对值的方法:
- 使用
abs()函数(需要包含cstdlib或bits/stdc++.h) - 手动判断:
cpp复制int diff = h1 - h2; if (diff < 0) diff = -diff;
对于初学者,建议优先使用标准库函数,代码更简洁且不易出错。
4.2 条件判断逻辑
本题的条件判断有两层:
- 首先比较差值大小
- 差值相同时再比较身高
这种多条件判断是编程中的常见模式,需要注意条件的顺序和逻辑关系。使用else if可以清晰地表达"否则如果"的逻辑关系。
4.3 循环结构应用
优化解法中使用了for循环来遍历数组,这是处理多个同类数据的有效方式。循环结构的要点包括:
- 初始化循环变量
- 设置循环条件
- 定义循环步进
在本例中,我们从i=2开始循环,跳过Alice自己的身高(h[1]),这是处理这类问题的常见技巧。
5. 常见错误与调试技巧
5.1 典型错误分析
-
忘记取绝对值:直接使用h1-h2计算差值,会导致负值影响比较结果
cpp复制// 错误写法 int c12 = h1 - h2; // 可能为负数 -
初始化不当:如果初始minc设为0,可能导致无法正确更新
cpp复制// 错误初始化 int minc = 0; // 任何差值都比0大,不会更新 -
条件判断不完整:只比较差值大小,忽略差值相等的情况
cpp复制// 不完整的判断 if (c < minc) { minc = c; ans = h[i]; } // 缺少差值相等时的处理
5.2 调试技巧
-
打印中间变量:在关键步骤后输出变量值,验证逻辑是否正确
cpp复制cout << "Comparing with h" << i << ": " << h[i] << endl; cout << "Current diff: " << c << ", min diff: " << minc << endl; -
边界值测试:测试身高差为0或最大的情况
- 输入:150 150 151 149(测试相同差值)
- 输入:100 199 198 101(测试最大差值)
-
单步调试:使用IDE的调试功能逐步执行,观察变量变化
6. 算法优化与扩展思考
6.1 时间复杂度分析
两种解法的时间复杂度都是O(1),因为无论哪种方法,都只进行了固定次数的比较(3次)。对于这种小规模问题,性能差异可以忽略不计。
但如果扩展到N个同学,第一种方法需要写N-1个比较块,而第二种方法只需调整循环次数,优势就显现出来了。
6.2 扩展思考
-
如果有多个相同身高差且相同身高的情况:虽然题目保证身高互不相同,但实际应用中可能需要考虑
- 可以记录所有符合条件的候选者
- 最后再按其他条件(如学号)选择
-
处理浮点数身高:如果身高是浮点数,需要注意浮点数比较的精度问题
cpp复制const double EPS = 1e-6; if (fabs(c - minc) < EPS) { // 视为差值相等 } -
扩展到多维特征:不仅考虑身高,还考虑其他特征(如年龄、兴趣等)
- 需要定义更复杂的距离函数
- 可能需要使用结构体或类来组织数据
7. 学习建议与资源推荐
对于刚开始学习C++和算法竞赛的同学,我有以下建议:
- 夯实基础:熟练掌握变量、循环、条件判断等基本语法
- 理解优先于记忆:明白每行代码的作用,而不是死记硬背
- 多做练习:通过实际编程来巩固知识
- 学会调试:掌握基本的调试技巧,能够自主发现问题
对于想要进一步提高的同学,可以尝试:
- 参加在线编程竞赛(如Codeforces、LeetCode周赛)
- 学习更复杂的数据结构(数组、链表、栈、队列)
- 研究常见算法(排序、搜索、递归)
这道"交朋友"的题目虽然简单,但包含了编程学习的核心要素。通过深入理解和练习这类基础题目,能够为后续更复杂的学习打下坚实基础。
