这道GESP C++一级考试题目"交朋友"看似简单,却蕴含了编程初学者需要掌握的多个核心概念。题目描述了一个生活化的场景:Alice要在班上三位同学中寻找与自己身高最接近的朋友。如果存在多个相同差距的同学,则选择其中最矮的一位。
这个题目主要考察以下几个编程基础能力:
对于初学者而言,这道题的价值在于它把抽象的编程概念具象化为一个容易理解的现实场景。通过解决这个问题,学生能够直观地理解如何用代码解决实际问题。
最直观的解法是分别计算Alice与其他三位同学的身高差,然后进行比较。具体步骤如下:
这种方法的优点是逻辑清晰,易于理解,适合编程初学者。它直接反映了我们人工解决问题的思考过程。
更进阶的解法是使用数组和循环结构,这体现了更好的编程实践:
这种方法减少了重复代码,更易于扩展。如果同学数量增加,只需调整循环次数即可,而不需要修改核心逻辑。
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()函数计算绝对值,比手动判断更简洁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;
}
代码优化点:
在本题中,计算身高差需要使用绝对值,因为身高差的方向不重要。C++中有两种计算绝对值的方法:
abs()函数(需要包含cstdlib或bits/stdc++.h)cpp复制int diff = h1 - h2;
if (diff < 0) diff = -diff;
对于初学者,建议优先使用标准库函数,代码更简洁且不易出错。
本题的条件判断有两层:
这种多条件判断是编程中的常见模式,需要注意条件的顺序和逻辑关系。使用else if可以清晰地表达"否则如果"的逻辑关系。
优化解法中使用了for循环来遍历数组,这是处理多个同类数据的有效方式。循环结构的要点包括:
在本例中,我们从i=2开始循环,跳过Alice自己的身高(h[1]),这是处理这类问题的常见技巧。
忘记取绝对值:直接使用h1-h2计算差值,会导致负值影响比较结果
cpp复制// 错误写法
int c12 = h1 - h2; // 可能为负数
初始化不当:如果初始minc设为0,可能导致无法正确更新
cpp复制// 错误初始化
int minc = 0; // 任何差值都比0大,不会更新
条件判断不完整:只比较差值大小,忽略差值相等的情况
cpp复制// 不完整的判断
if (c < minc) {
minc = c;
ans = h[i];
}
// 缺少差值相等时的处理
打印中间变量:在关键步骤后输出变量值,验证逻辑是否正确
cpp复制cout << "Comparing with h" << i << ": " << h[i] << endl;
cout << "Current diff: " << c << ", min diff: " << minc << endl;
边界值测试:测试身高差为0或最大的情况
单步调试:使用IDE的调试功能逐步执行,观察变量变化
两种解法的时间复杂度都是O(1),因为无论哪种方法,都只进行了固定次数的比较(3次)。对于这种小规模问题,性能差异可以忽略不计。
但如果扩展到N个同学,第一种方法需要写N-1个比较块,而第二种方法只需调整循环次数,优势就显现出来了。
如果有多个相同身高差且相同身高的情况:虽然题目保证身高互不相同,但实际应用中可能需要考虑
处理浮点数身高:如果身高是浮点数,需要注意浮点数比较的精度问题
cpp复制const double EPS = 1e-6;
if (fabs(c - minc) < EPS) {
// 视为差值相等
}
扩展到多维特征:不仅考虑身高,还考虑其他特征(如年龄、兴趣等)
对于刚开始学习C++和算法竞赛的同学,我有以下建议:
对于想要进一步提高的同学,可以尝试:
这道"交朋友"的题目虽然简单,但包含了编程学习的核心要素。通过深入理解和练习这类基础题目,能够为后续更复杂的学习打下坚实基础。