B3988 [语言月赛 202406] 天然气计价 题解
Source & Knowledge
2024 年 6 月语言月赛,由洛谷网校入门计划/基础计划提供。
题目大意
天然气的常用单位是立方米,采用阶梯计费。给出一年中每个月的天然气使用量,求每个月需要付的天然气费用。
阶梯计费的规则是,对于每个月的每一立方米天然气,都要考虑本年到这一立方米天然气为止(包括这一立方米天然气),使用的天然气的全部数量。根据这个数量套入题目给出的规则计算这一立方米天然气的价钱。最后累加。
题目分析
本题考察循环结构的运用。
做法 1
首先定义了一个名为 f 的函数,记录从年初到现在的累计用气量。
- 如果
x小于等于 310,那么费用就是x乘以 3 元/立方米。 - 如果
x在 310 到 520 之间,那么费用包括两部分:前 310 立方米的费用(310 乘以 3 元/立方米)和超出 310 立方米的部分(x - 310)乘以 3.3 元/立方米。 - 如果
x大于 520,那么费用包括三部分:前 310 立方米的费用、310 到 520 立方米的费用(这部分同上),以及超出 520 立方米的部分(x - 520)乘以 4.2 元/立方米。
初始化一个变量 last 为 0,用于记录上一个月底(或年初)的累计用气量。
- 循环读取 12 个月的用气量,每次读取一个值赋给变量
now。 - 对于每个月,计算从年初到这个月底的累计用气量(
last + now),然后用这个累计用气量计算总费用(f(last + now))。 - 然后,计算这个月相对于上个月的用气量所产生的费用,即
f(last + now) - f(last)。 - 输出这个月的费用,并更新
last的值为这个月底的累计用气量(last + now)。
// 计算全年的费用
double f(int x){
if(x <= 310)
return x * 3.0;
else if (x <= 520)
return 310 * 3.0 + (x - 310) * 3.3;
else
return 310 * 3.0 + (520 - 310) * 3.3
+ (x - 520) * 4.2;
}
// 主函数
int last = 0, now;
for(int i = 1; i <= 12; i++){
cin >> now;
printf("%.1lf\n", f(last + now) - f(last));
// 这个月全年减上个月全年的费用。
last += now;
}
做法 2
可以发现,每年使用的天然气的价格至多在前
所以,可以在计算价钱时,按照这样的步骤:
- 如果当前使用的天然气总数量
< 520 立方米,那么就一立方米、一立方米计算; - 否则,直接按照最高价来计算(总价
= 单价\times 数量),不需要每一立方米计算一次。
上述步骤可以使用一个 while 来完成,大致思路是 while (当前使用的数量 < 520 && 当月还有没计算的天然气) {...}。
这样既可以保证计算简单,又不会超时。
int n = 12;
int cur = 0; // cur 记录当前使用的天然气总量
for (int i = 1; i <= n; i++) {
int a;
scanf("%d", &a);
double ans = 0.0;
while (cur < 520 && a > 0) {
if (cur < 310) {
ans += 3;
} else {
ans += 3.3;
}
a--;
cur++;
}
ans += a * 4.2;
printf("%.1lf\n", ans);
}