CSP-X 2018真题 | 快递费用 luogu-B4073
CSP-X 2018真题-快递费用,一道结合分支判断与简单数学运算的入门题目,考察条件语句(或数组映射)和向上取整的处理技巧。适合GESP二级及以上考生练习,难度⭐☆。
B4073 [CSP-X 2018] 快递费用
题目要求
题目描述
某快递公司按邮寄物品的重量收费,收费标准如下:
重量在 克以内的,一律 元;
超过 克的,超重的部分按每 克加收费用。超出的重量不足 克的,按 克计算。例如: 克,超重 克,需加收两份费用。
根据目的地的不同,加收的费用是不一样的。快递公司划分了五个目的地区域:
- 区域 :每超重 克加收 元;
- 区域 :每超重 克加收 元;
- 区域 :每超重 克加收 元;
- 区域 :每超重 克加收 元;
- 区域 :每超重 克加收 元。
给出物品的重量 和目的地区域编号 ,请你计算快递费用。
输入格式
一行,两个正整数 。
输出格式
一行,一个整数,表示快递费用。
输入输出样例 #1
输入 #1
1020 3输出 #1
38说明/提示
克的物品寄到区域 ,前 克收费 元;
超重 克,还需缴纳 份加收的费用;
区域 每超重 克加收 元,共计: 元。
数据保证 ,。
题目分析
本题是一道结合分支判断与数学运算的入门题,考察对分段计费规则的理解和实现。
解题思路分析:
基础费用:
- 无论物品多重,前 克的费用固定为 元。
- 如果 ,直接输出 即可。
超重部分的计算:
- 超出重量为 克,设超出重量为 。
- 超出的部分按每 克一份来计费,不足 克的按 克计算。这实际上就是对超重部分 除以 后做向上取整。
- 向上取整的份数公式为:。
向上取整技巧详解:
C++ 中的整数除法(
/)是天然向下取整的,即直接截断小数部分。例如 (余数 被丢弃)。但本题要求"不足 克也按 克算",也就是需要向上取整,即 应该得到 。向上取整的通用公式为:
其原理是:在做除法之前,给被除数加上 (即除数减一)。这样做的效果是——
- 如果 能被 整除(即没有余数),加上 后仍然不会多凑出一个 ,向下取整的结果不变。例如:,则 ,与 结果一致。
- 如果 不能被 整除(即有余数),原本余数被截断导致少算了一份,但加上 后,余数部分被"顶"过了下一个整除点,向下取整的结果恰好多出 ,实现了向上取整。例如:,原本 ,但 ,符合预期。
在本题中,,,代入公式得:
所以在代码中直接写
(w - 1) / 500即可。虽然化简后的表达式看上去和"超重部分除以500"没有直接联系了,但它确实是由向上取整公式严格推导而来的。这是一个在竞赛和日常编程中非常常用的整数运算技巧,建议牢记。
区域费率的映射:
- 五个区域对应五种不同的加收单价:。
- 可以使用
if-else分支逐一判断,但更简洁优雅的做法是使用数组映射:将五个费率存入数组,用区域编号作为下标直接取值。
最终费用:
- 总费用 。
数据类型注意:
- 最大可达 ,超重份数最多约为 ,乘以最大单价 后约为 ,加上基础费用 后远小于
int的上限,因此使用int即可安全存储结果。
- 最大可达 ,超重份数最多约为 ,乘以最大单价 后约为 ,加上基础费用 后远小于
复杂度分析:
- 时间复杂度:,只需常数次运算。
- 空间复杂度:,只使用几个变量和一个固定大小的数组。
示例代码
#include <iostream>
int main() {
int w, n;
std::cin >> w >> n;
// 五个区域对应的超重加收单价,下标 1~5 对应区域 1~5
int rate[] = {0, 4, 6, 9, 10, 17};
// 基础费用 20 元
int cost = 20;
// 如果超重,计算超重份数并加收费用
if (w > 500) {
// 向上取整:ceil((w-500)/500) = (w-500+499)/500 = (w-1)/500
int extra = (w - 1) / 500;
cost += extra * rate[n];
}
std::cout << cost << std::endl;
return 0;
}本文由coderli.com原创,按照CC BY-NC-SA 4.0 进行授权
所有代码已上传至Github:https://github.com/lihongzheshuai/yummy-code
“luogu-”系列题目可在 洛谷题库 在线评测。
“bcqm-”系列题目可在 编程启蒙题库 在线评测。
GESP/CSP认证交流QQ群: 688906745
