Charley 0 时刻从起点出发,途中遇到更快的人就跟上去;答案就是 t>=0 的同行人中 t + ceil(16200/v) 的最小值。
OJ: roj
题目 ID: 1227
难度:入门
标签:思维数学python
创建: 2026-09-30 00:42
更新: 2026-10-05 05:57
题目描述
起点到终点相距 4500 米。Charley 在时刻 0 从起点出发,必须与同行人同速骑行;遇到速度更快的人就跟上去。给出 n 个同行人的速度 v(km/h)与出发时间 t(t<0 表示提早出发),多组数据直到 n=0。求 Charley 到达终点的时间,结果向上取整。样例:第一组输入 4\n20 0\n25 -155\n27 190\n30 240 输出 780;第二组输入 2\n21 0\n22 34 输出 771。
思路
观察一:Charley 的到达时刻恰等于某个 t≥0 的同行人独自骑到的时刻,所以问题坍缩成"挑出最小 t+ceil(16200/v)";其中 16200=4500×3.6 是把 km/h 换算成 m/s 后的乘子。观察二:t<0 的同行人 Charley 出发时已在前方,永远追不上,直接跳过。
参考代码
Python 版:
python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-10-01 10:15
# update_at: 2026-10-01 10:15
import sys
METERS = 4500 # 赛道长度(米)
DIST = METERS * 36 // 10 # 速度是 km/h,换算后 16200:除以 v 恰得骑行秒数
def solve() -> None:
data = iter(map(int, sys.stdin.buffer.read().split()))
out: list[str] = []
while (n := next(data)) != 0: # n = 0 表示输入结束
arrivals = [] # Charley 可跟随(出发时刻不早于 0)的人的到达时刻
for _ in range(n):
v, t = next(data), next(data) # 速度(km/h)、出发时刻(可为负)
if t >= 0:
arrivals.append(t + -(-DIST // v)) # ceil 除法:向上取整的骑行秒数
out.append(str(min(arrivals, default=999999999))) # 无人可跟时与参考实现一致
print('\n'.join(out))
if __name__ == "__main__":
solve()C++ 版(同一算法):
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-10-05 05:57
* update_at: 2026-10-05 05:57
*/
// main.cpp:Charley 必须与同行人同速跟随;挑出 t>=0 的人中最早到达终点的时刻。
#include <iostream>
typedef long long ll;
const ll DIST = 4500; // 赛道长度(米)
const ll NUM = DIST * 36 / 10; // 16200:4500m / (v km/h) 换算到秒数时除以 v 的值
int main() {
ll n;
std::cin >> n;
while (n != 0) { // n = 0 表示输入结束
ll best = (ll)9e18; // 本组答案:所有可用同行人到达时刻的最小值
for (ll i = 0; i < n; i++) {
ll v, t;
std::cin >> v >> t;
if (t < 0) continue; // 提前出发:Charley 出发时已在前方,追不上,跳过
ll ride = (NUM + v - 1) / v; // 骑 4500m 需要 ceil(16200 / v) 秒
ll arrive = t + ride; // 该同行人独自到达终点的时刻
if (arrive < best) best = arrive;
}
std::cout << best << '\n';
std::cin >> n;
}
return 0;
}