专栏文章

B4342 [语言月赛 202506] 火车优惠

B4342题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mip2i0gq
此快照首次捕获于
2025/12/03 05:05
3 个月前
此快照最后确认于
2025/12/03 05:05
3 个月前
查看原文

Source & Knowledge

2024 年 6 月语言月赛,由洛谷网校入门计划/基础计划提供。

题目大意

小明想乘火车旅行 xx 公里。车票价格如下:
  • 1101 \sim 10 公里,每公里 2020 元;
  • 超过 1010 公里至 5050 公里部分,每 55 公里 8080 元(不足 55 公里也按 55 公里计算);
  • 超过 5050 公里部分,每 1010 公里 120120 元(不足 1010 公里也按 1010 公里计算)。
小明可以用一张票两张票,票的公里数可以随意拆分,目标是总费用最少。求完成 xx 公里所需的最小花费。

题目分析

本题的核心在于两个方面:
  1. 设计单张票的计费方法
  2. 在所有一张票或两张票的拆分方式中,枚举求出总费用的最小值

单张票计费方法

我们首先仅考虑一张票,计算长度为 dd 公里的单张车票价格:
  • 1010 公里按每公里 2020 元计费;
  • d>10d > 10,其超出部分最多至 5050 公里部分,分为若干个 55 公里段,不足 55 公里部分按 55 公里算,每段收费 8080 元;
  • d>50d > 50,其超出部分继续按照每 1010 公里 120120 元计费,若不足 1010 公里也按 1010 公里计费。
CPP
int money = 0;
money += 20 * min(d, 10);
d -= min(d, 10);
int per5km = min(d, 50 - 10) / 5;
if (min(d, 50 - 10) % 5 != 0) {
    per5km++;
}
money += 80 * per5km;
d -= min(d, 50 - 10);
int per10km = d / 10;
if (d % 10 != 0) {
    per10km++;
}
money += 120 * per10km;

枚举所有可能拆分方式

在明确一张票的计算方式后,我们可以自然地枚举 0ix0 \le i \le x,设第一张票走 ii 公里,第二张票走 xix - i 公里(可为 00 公里)。对于每一组划分,计算 ii 公里的费用和 xix - i 公里的费用的总和。
在上述的所有总和中取最小值,即为答案,最终输出即可。

评论

0 条评论,欢迎与作者交流。

正在加载评论...