人设:毒舌
2026-07-22 13:00:22
发布于:浙江
(推了推不存在的眼镜,嘴角勾起一抹嘲讽的弧度)哼,这种题也敢拿出来?行吧行吧,本大爷就勉为其难给你讲讲你那破代码到底在搞什么鬼。
- 解题思路(一步一步推导,别眨眼)
第一步:读懂题目,别像个憨憨一样迷路
独木桥长度 (L),坐标从 (1) 到 (L),士兵速度 (1),走到 (0) 或 (L+1) 就算撤完。两个士兵面对面相遇会转身,但转身时间不计。你连他们初始方向都不知道,只能算出最少和最多需要的时间。
第二步:开动你聪明的小脑瓜——相遇转身等于互相穿过
两个士兵面对面相遇,转身继续走——这不就相当于他们互相穿过然后继续走吗?因为士兵长得都一样,你根本分不清谁是谁。所以每个士兵独立地往左或往右走,方向可以随便选(虽然实际方向固定,但你可以通过调整“相遇”来等效)。于是问题变成:每个士兵有一个坐标 (a),他可以向左用 (a) 时间到 (0),或向右用 (L-a+1) 时间到 (L+1)。现在你要选方向,使得所有士兵都撤完的时间最小或最大。
第三步:最小时间?给爷往近处跑!
要最小化全部撤离时间,那每个士兵肯定都往离自己最近的端点跑。这样每个士兵的撤离时间就是 (\min(a, L-a+1))。然后全部撤离需要这些时间中的最大值——因为最慢的那个决定了最终时间。所以最小时间 (mi = \max\limits_{i} \min(a_i, L-a_i+1))。
第四步:最大时间?给爷往远处浪!
要最大化全部撤离时间,那就每个士兵都往最远的端点跑。每个士兵的撤离时间就是 (\max(a, L-a+1))。同样取最大值:(ma = \max\limits_{i} \max(a_i, L-a_i+1))。
第五步:你代码里那个if-else是啥玩意儿?
哦,你把每个士兵的 (a) 和 (L-a+1) 比较,如果左边小,说明近端在左,远端在右。那么最小时间取左边(近端),最大时间取右边(远端)。反之亦然。然后每次更新 (mi) 和 (ma) 为最大值。完美,就是干这个的。注意如果 (n=0),那循环不执行,(mi=ma=0),合理。
第六步:样例验证
(L=4),士兵坐标1和3。
士兵1:左1,右4。左<右,mi取max(0,1)=1,ma取max(0,4)=4。
士兵3:左3,右2。左>右,mi取max(1,2)=2,ma取max(4,3)=4。
输出“2 4”,和样例一样。看,本大爷没骗你吧?
2. 代码注释(给你那破代码打上注释,别感动哭了)
#include<bits/stdc++.h>
using namespace std;
int main(){
int l, n; // 独木桥长度 l,士兵数 n
int a; // 当前士兵坐标
scanf("%d%d", &l, &n); // 读入 l 和 n
int mi = 0, ma = 0; // 最小时间 mi,最大时间 ma,初始为 0(没有士兵时时间为 0)
for(int i = 1; i <= n; i++){ // 遍历每一个士兵,感受他们的存在!
scanf("%d", &a); // 读入士兵坐标
// 判断:向左走时间 a,向右走时间 l-a+1
if(a < l-a+1){ // 如果向左走更快!
mi = max(mi, a); // 最小时间取向左走时间 a 的最大值!
ma = max(ma, l-a+1); // 最大时间取向右走时间 l-a+1 的最大值!
}
else{
mi = max(mi, l-a+1);
ma = max(ma, a); // 最大时间取向左走时间 a 的最大值!
}
}
printf("%d %d", mi, ma); // 输出最终答案!最小时间与最大时间!
return 0;// 你还用return0啊?不知道他会自动返回码
}
(翻白眼)好了,看完了就赶紧去刷下一题吧,别在这儿浪费本大爷的时间了。
此题解仅供参考,无情绪带入
这里空空如也








有帮助,赞一个