在 GESP 一级的经典题目「交朋友」中,我们需要帮 Alice 找到身高最接近的朋友,若有多人符合,则选择其中最矮的那位。这道题看似简单,却能衍生出多种不同的解题思路,非常适合用来锻炼编程逻辑。不过对于考一级的小朋友还是太难了。不过别抱怨,让我们勤学苦练到没有意外!


方法一:逐个比较法(最基础推荐)
核心思想
直接遍历所有小朋友,逐个计算与 Alice 的身高差,动态更新最优解。
- 代码特点
无数组、无复杂循环,仅用基础变量和 if判断,代码最短、逻辑最直观。 - 优势
完全贴合 GESP 一级知识点,新手极易理解,几乎无 bug 风险。 - 适用场景
刚接触编程、只掌握变量与条件判断的初学者。 #include <iostream>using namespace std;int main() {int alice, h1, h2, h3;cin >> alice >> h1 >> h2 >> h3;int best = h1;int min_diff = alice - h1;if (min_diff < 0) min_diff = -min_diff;int diff = alice - h2;if (diff < 0) diff = -diff;if (diff < min_diff || (diff == min_diff && h2 < best)) {min_diff = diff; best = h2;}diff = alice - h3;if (diff < 0) diff = -diff;if (diff < min_diff || (diff == min_diff && h3 < best)) {min_diff = diff; best = h3;}cout << best << endl;return 0;}方法二:数组遍历法(代码复用优化)
核心思想
将小朋友身高存入数组,用循环遍历替代重复的比较代码,提升代码简洁性。
#include <iostream>using namespace std;int main() {int h[4];cin >> h[0] >> h[1] >> h[2] >> h[3];int best = h[1];int min_diff = h[0] - h[1];if (min_diff < 0) min_diff = -min_diff;for (int i = 2; i < 4; i++) {int diff = h[0] - h[i];if (diff < 0) diff = -diff;if (diff < min_diff || (diff == min_diff && h[i] < best)) {min_diff = diff; best = h[i];}}cout << best << endl;return 0;}方法三:排序位置判断法(直观生活逻辑)
核心思想
先将所有身高排序,找到 Alice 在序列中的位置,再通过比较左右邻居确定最优解。
- 代码特点
引入数组和单循环,避免重复书写相同逻辑,结构更清晰。 - 优势
适合理解数组与循环的配合,为后续学习打下基础。 - 适用场景
已掌握数组基础、希望简化重复代码的学习者。
#include <bits/stdc++.h>using namespace std;int main() {int a[4];cin >> a[0] >> a[1] >> a[2] >> a[3];int alice = a[0];// 冒泡排序for (int i = 0; i < 3; i++) {for (int j = 0; j < 3 - i; j++) {if (a[j] > a[j+1]) swap(a[j], a[j+1]);}}int pos = 0;for (int i = 0; i < 4; i++) {if (a[i] == alice) { pos = i; break; }}int friend_h;if (pos == 0) friend_h = a[1];else if (pos == 3) friend_h = a[2];else {int left_diff = alice - a[pos-1];int right_diff = a[pos+1] - alice;if (left_diff < right_diff) friend_h = a[pos-1];else if (right_diff < left_diff) friend_h = a[pos+1];else friend_h = a[pos-1];}cout << friend_h << endl;return 0;}
方法四:差值 + 身高联合排序法(进阶排序思维)
- 代码特点
需要手动实现冒泡排序,代码量稍多,但逻辑完全符合生活直觉。 - 优势
将抽象问题转化为 “找邻居” 的具象场景,便于理解边界情况。 - 适用场景
想锻炼排序能力、喜欢具象化思考的同学。 将「身高差」和「身高本身」绑定,通过一次排序同时满足 “差距最小” 和 “更矮” 的规则。
#include<bits/stdc++.h>using namespace std;intmain(){int alice, h1, h2, h3;cin >> alice >> h1 >> h2 >> h3;int diff[3], height[3];// 计算差值diff[0] = abs(alice - h1); height[0] = h1;diff[1] = abs(alice - h2); height[1] = h2;diff[2] = abs(alice - h3); height[2] = h3;// 联合排序for (int i = 0; i < 2; i++) {for (int j = 0; j < 2 - i; j++) {if (diff[j] > diff[j+1]) {swap(diff[j], diff[j+1]);swap(height[j], height[j+1]);} else if (diff[j] == diff[j+1] && height[j] > height[j+1]) {swap(height[j], height[j+1]);}}}cout << height[0] << endl;return 0;}方法五:枚举法(穷举所有情况)
核心思想
由于只有 3 个小朋友,直接穷举所有可能的比较情况,用 if-else完成判断。- 代码特点
用两个数组分别存储差值和身高,排序时先比差值、再比身高。 - 优势
思路新颖,能锻炼多关键字排序的思维,扩展性强。 - 适用场景
希望进阶、探索排序灵活应用的学习者。 由于只有 3 个小朋友,直接穷举所有可能的比较情况,用
if-else完成判断。#include<bits/stdc++.h>using namespace std;intmain(){int alice, h1, h2, h3;cin >> alice >> h1 >> h2 >> h3;int d1 = abs(alice - h1);int d2 = abs(alice - h2);int d3 = abs(alice - h3);int best;if (d1 < d2 && d1 < d3) best = h1;else if (d2 < d1 && d2 < d3) best = h2;else if (d3 < d1 && d3 < d2) best = h3;else if (d1 == d2 && d1 < d3) best = (h1 < h2) ? h1 : h2;else if (d1 == d3 && d1 < d2) best = (h1 < h3) ? h1 : h3;else if (d2 == d3 && d2 < d1) best = (h2 < h3) ? h2 : h3;else best = min({h1, h2, h3});cout << best << endl;return 0;}方法六:向外扩散枚举法(巧妙暴力思路) - 核心思想
从 Alice 的身高开始,先往矮的方向(减 1)、再往高的方向(加 1)一步步扩散,找到第一个存在的身高。 - 代码特点
无循环、无数组,完全用条件判断覆盖所有场景,逻辑直白。 - 优势
极端适合初学者理解 “所有可能性” 的思维,代码无任何隐藏逻辑。 - 适用场景
刚学 if-else、想彻底理清所有边界条件的新手。 核心思想
从 Alice 的身高开始,先往矮的方向(减 1)、再往高的方向(加 1)一步步扩散,找到第一个存在的身高。
- 代码特点
用死循环 + break实现,代码极简,自动满足 “更矮优先” 的规则。 - 优势
思路极具创造性,完全贴合题目整数身高的特性,是 GESP 一级的 “高分巧解” 代表。 - 适用场景
喜欢探索巧思、想提升编程趣味性的同学。 #include <iostream>using namespace std;int main() {int h, h1, h2, h3;cin >> h >> h1 >> h2 >> h3;for (int i = 0;; i++) {if (h-i == h1 || h-i == h2 || h-i == h3) {cout << h-i; break;}if (h+i == h1 || h+i == h2 || h+i == h3) {cout << h+i; break;}}return 0;}
写在最后
这道「交朋友」的题目,看似简单,却能衍生出 6 种截然不同的思路,这正是编程的魅力所在 ——没有唯一正确的解法,只有更适合当前场景的思路。
对于 GESP 一级备考的同学,我最推荐先掌握「逐个比较法」和「枚举法」,这两种方法最稳妥、最不容易出错;学有余力的同学可以尝试「向外扩散法」,感受编程巧思带来的乐趣。