1. 题目背景与需求分析
这道来自CSP-X2021山东赛区的题目"发送快递"考察的是基础编程能力和条件判断逻辑的应用。题目要求我们根据快递件数和用户是否选择加急这两个输入参数,按照给定的计费规则计算出最终的快递费用。
具体计费规则如下:
- 基础运费规则:
- 件数≤10时:首重5元,续重每件2元
- 件数>10时:首重5元,续重每件1元
- 加急服务费:
- 选择加急:总运费×1.5(四舍五入到整数)
- 不加急:按原价计算
例如:
- 输入:8件,不加急 → 5+(8-1)×2=19元
- 输入:12件,加急 → [5+(12-1)×1]×1.5=24元(16×1.5=24)
2. 解题思路与算法设计
2.1 输入处理框架
首先需要设计合理的输入输出接口。根据题目描述,输入是两个参数:
- 快递件数n(正整数)
- 是否加急isUrgent(布尔值或字符表示)
在C++中,我们可以使用cin来读取这两个参数:
cpp复制int n;
char urgent;
cin >> n >> urgent; // 假设用'y'表示加急,'n'表示不加急
bool isUrgent = (urgent == 'y');
2.2 运费计算逻辑
核心计算可以分为两个步骤:
cpp复制int baseCost; // 基础运费
if (n <= 10) {
baseCost = 5 + (n - 1) * 2;
} else {
baseCost = 5 + (n - 1) * 1;
}
2.3 加急费用处理
加急费用需要特别注意四舍五入的处理。C++中可以使用以下方法实现四舍五入:
cpp复制int totalCost;
if (isUrgent) {
totalCost = static_cast<int>(round(baseCost * 1.5));
} else {
totalCost = baseCost;
}
注意:需要包含
头文件才能使用round函数
3. 完整代码实现
结合上述思路,完整的C++实现如下:
cpp复制#include <iostream>
#include <cmath>
using namespace std;
int main() {
int n;
char urgent;
cin >> n >> urgent;
bool isUrgent = (urgent == 'y');
int baseCost;
if (n <= 10) {
baseCost = 5 + (n - 1) * 2;
} else {
baseCost = 5 + (n - 1) * 1;
}
int totalCost;
if (isUrgent) {
totalCost = static_cast<int>(round(baseCost * 1.5));
} else {
totalCost = baseCost;
}
cout << totalCost << endl;
return 0;
}
4. 代码优化与边界测试
4.1 代码优化建议
- 使用常量代替魔法数字:
cpp复制const int BASE_FEE = 5;
const double URGENT_RATE = 1.5;
- 简化条件判断:
cpp复制int unitCost = (n <= 10) ? 2 : 1;
int baseCost = BASE_FEE + (n - 1) * unitCost;
4.2 边界测试用例
好的程序应该能处理各种边界情况:
-
最小件数测试:
- 输入:1 n → 应输出5
- 输入:1 y → 应输出8(5×1.5=7.5四舍五入)
-
临界值测试:
- 输入:10 n → 5+9×2=23
- 输入:11 n → 5+10×1=15
-
大数测试:
- 输入:100 y → 5+99×1=104 → 104×1.5=156
5. 常见错误与调试技巧
5.1 新手常见错误
-
忘记处理n=1的情况:
- 错误写法:
cost = 5 + (n) * 2(当n=1时多算一件)
- 错误写法:
-
四舍五入实现错误:
- 错误写法:
int(totalCost * 1.5)(直接截断而非四舍五入)
- 错误写法:
-
输入处理不严谨:
- 假设输入总是有效的,没有考虑非法输入的情况
5.2 调试技巧
- 使用中间变量输出:
cpp复制cout << "baseCost: " << baseCost << endl;
-
单元测试框架:
可以编写简单的测试函数验证各个部分的正确性 -
使用assert进行验证:
cpp复制assert(calculateFee(1, false) == 5);
6. 算法扩展思考
虽然本题相对简单,但可以延伸思考更复杂的快递计费系统:
- 多级计费:不同重量区间不同单价
- 地区附加费:不同目的地不同基础费用
- 会员折扣系统:根据会员等级给予不同折扣
例如,考虑重量因素的实现可能如下:
cpp复制struct Package {
int count;
double weight;
bool isUrgent;
string destination;
};
double calculateFee(const Package& pkg) {
// 更复杂的计费逻辑
}
7. 信奥备赛建议
-
基础语法要扎实:
- 熟练掌握条件判断、循环、基本运算符
- 理解整数与浮点数运算的区别
-
培养严谨的编程习惯:
- 总是考虑边界条件
- 使用有意义的变量名
- 添加必要的注释
-
刷题策略:
- 从简单题开始建立信心
- 每道题都要彻底理解
- 建立自己的错题本
这道"发送快递"题目虽然简单,但很好地训练了基础编程能力和逻辑思维。在实际比赛中,这类题目需要快速准确地完成,为后面的难题节省时间。建议初学者可以尝试不同的实现方式,比较它们的优劣,并思考如何扩展更复杂的功能。
