摘要 :本文详细解析了阶梯水费计算问题。题目要求实现一个分段函数:当用水量 x ≤ 15 吨时,水费 y = 4x/3;当 x > 15 吨时,y = 2.5x - 17.5。文章从分段函数逻辑 、边界条件处理 (x=15 处的连续性)、浮点数精度注意事项 、输出格式化要求 等方面进行了深入分析,并提供了可视化图表和完整的 C 语言实现代码。关键点包括:使用 double 类型保证精度、if (x <= 15) 的条件判断、printf("%.2f", y) 格式化输出,以及函数在 x=15 处连续(y=20)的数学特性。
题目描述
为鼓励居民节约用水,自来水公司采取按用水量阶梯式计价的办法,居民应交水费y(元)与月用水量 x(吨)相关:当 x 不超过 15 吨时,y = 4x / 3;超过后,y = 2.5x − 17.5。请编写程序实现水费的计算。
输入格式:
输入在一行中给出非负实数 x。
输出格式:
在一行输出应交的水费,精确到小数点后 2 位。
输入样例:
in
12
in
16
输出样例:
out
16.00
out
22.50
解题思路
本题的核心是实现一个分段函数,根据用水量 x 的不同范围采用不同的计费公式。下面从几个方面详细分析:
1. 分段函数逻辑
#mermaid-svg-mkYWvoxs7CK4ICcE{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-mkYWvoxs7CK4ICcE .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-mkYWvoxs7CK4ICcE .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-mkYWvoxs7CK4ICcE .error-icon{fill:#552222;}#mermaid-svg-mkYWvoxs7CK4ICcE .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mkYWvoxs7CK4ICcE .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-mkYWvoxs7CK4ICcE .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mkYWvoxs7CK4ICcE .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mkYWvoxs7CK4ICcE .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-mkYWvoxs7CK4ICcE .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mkYWvoxs7CK4ICcE .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mkYWvoxs7CK4ICcE .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mkYWvoxs7CK4ICcE .marker.cross{stroke:#333333;}#mermaid-svg-mkYWvoxs7CK4ICcE svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mkYWvoxs7CK4ICcE p{margin:0;}#mermaid-svg-mkYWvoxs7CK4ICcE .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-mkYWvoxs7CK4ICcE .cluster-label text{fill:#333;}#mermaid-svg-mkYWvoxs7CK4ICcE .cluster-label span{color:#333;}#mermaid-svg-mkYWvoxs7CK4ICcE .cluster-label span p{background-color:transparent;}#mermaid-svg-mkYWvoxs7CK4ICcE .label text,#mermaid-svg-mkYWvoxs7CK4ICcE span{fill:#333;color:#333;}#mermaid-svg-mkYWvoxs7CK4ICcE .node rect,#mermaid-svg-mkYWvoxs7CK4ICcE .node circle,#mermaid-svg-mkYWvoxs7CK4ICcE .node ellipse,#mermaid-svg-mkYWvoxs7CK4ICcE .node polygon,#mermaid-svg-mkYWvoxs7CK4ICcE .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-mkYWvoxs7CK4ICcE .rough-node .label text,#mermaid-svg-mkYWvoxs7CK4ICcE .node .label text,#mermaid-svg-mkYWvoxs7CK4ICcE .image-shape .label,#mermaid-svg-mkYWvoxs7CK4ICcE .icon-shape .label{text-anchor:middle;}#mermaid-svg-mkYWvoxs7CK4ICcE .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-mkYWvoxs7CK4ICcE .rough-node .label,#mermaid-svg-mkYWvoxs7CK4ICcE .node .label,#mermaid-svg-mkYWvoxs7CK4ICcE .image-shape .label,#mermaid-svg-mkYWvoxs7CK4ICcE .icon-shape .label{text-align:center;}#mermaid-svg-mkYWvoxs7CK4ICcE .node.clickable{cursor:pointer;}#mermaid-svg-mkYWvoxs7CK4ICcE .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-mkYWvoxs7CK4ICcE .arrowheadPath{fill:#333333;}#mermaid-svg-mkYWvoxs7CK4ICcE .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-mkYWvoxs7CK4ICcE .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-mkYWvoxs7CK4ICcE .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mkYWvoxs7CK4ICcE .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-mkYWvoxs7CK4ICcE .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mkYWvoxs7CK4ICcE .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-mkYWvoxs7CK4ICcE .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-mkYWvoxs7CK4ICcE .cluster text{fill:#333;}#mermaid-svg-mkYWvoxs7CK4ICcE .cluster span{color:#333;}#mermaid-svg-mkYWvoxs7CK4ICcE div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-mkYWvoxs7CK4ICcE .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-mkYWvoxs7CK4ICcE rect.text{fill:none;stroke-width:0;}#mermaid-svg-mkYWvoxs7CK4ICcE .icon-shape,#mermaid-svg-mkYWvoxs7CK4ICcE .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mkYWvoxs7CK4ICcE .icon-shape p,#mermaid-svg-mkYWvoxs7CK4ICcE .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-mkYWvoxs7CK4ICcE .icon-shape .label rect,#mermaid-svg-mkYWvoxs7CK4ICcE .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mkYWvoxs7CK4ICcE .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-mkYWvoxs7CK4ICcE .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-mkYWvoxs7CK4ICcE :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
输入用水量 x
x ≤ 15?
y = 4x / 3
y = 2.5x - 17.5
输出 y (保留2位小数)
图1:水费计算程序流程图 - 展示了从输入到输出的完整决策流程。
题目给出的水费计算规则是一个典型的分段函数:
-
第一段(x ≤ 15) :
y = 4x / 3- 当用水量不超过 15 吨时,单价为 4/3 ≈ 1.333 元/吨
- 这是一个线性函数,斜率较小,属于较低单价区间
-
第二段(x > 15) :
y = 2.5x - 17.5- 当用水量超过 15 吨后,单价变为 2.5 元/吨,但有一个固定减免额 17.5 元
- 这实际上是一个「超额累进」计费方式,超过部分按较高单价计算
2. 边界条件处理
#mermaid-svg-niSI8Bs31L5I0Kah{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-niSI8Bs31L5I0Kah .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-niSI8Bs31L5I0Kah .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-niSI8Bs31L5I0Kah .error-icon{fill:#552222;}#mermaid-svg-niSI8Bs31L5I0Kah .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-niSI8Bs31L5I0Kah .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-niSI8Bs31L5I0Kah .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-niSI8Bs31L5I0Kah .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-niSI8Bs31L5I0Kah .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-niSI8Bs31L5I0Kah .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-niSI8Bs31L5I0Kah .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-niSI8Bs31L5I0Kah .marker{fill:#333333;stroke:#333333;}#mermaid-svg-niSI8Bs31L5I0Kah .marker.cross{stroke:#333333;}#mermaid-svg-niSI8Bs31L5I0Kah svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-niSI8Bs31L5I0Kah p{margin:0;}#mermaid-svg-niSI8Bs31L5I0Kah .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-niSI8Bs31L5I0Kah .cluster-label text{fill:#333;}#mermaid-svg-niSI8Bs31L5I0Kah .cluster-label span{color:#333;}#mermaid-svg-niSI8Bs31L5I0Kah .cluster-label span p{background-color:transparent;}#mermaid-svg-niSI8Bs31L5I0Kah .label text,#mermaid-svg-niSI8Bs31L5I0Kah span{fill:#333;color:#333;}#mermaid-svg-niSI8Bs31L5I0Kah .node rect,#mermaid-svg-niSI8Bs31L5I0Kah .node circle,#mermaid-svg-niSI8Bs31L5I0Kah .node ellipse,#mermaid-svg-niSI8Bs31L5I0Kah .node polygon,#mermaid-svg-niSI8Bs31L5I0Kah .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-niSI8Bs31L5I0Kah .rough-node .label text,#mermaid-svg-niSI8Bs31L5I0Kah .node .label text,#mermaid-svg-niSI8Bs31L5I0Kah .image-shape .label,#mermaid-svg-niSI8Bs31L5I0Kah .icon-shape .label{text-anchor:middle;}#mermaid-svg-niSI8Bs31L5I0Kah .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-niSI8Bs31L5I0Kah .rough-node .label,#mermaid-svg-niSI8Bs31L5I0Kah .node .label,#mermaid-svg-niSI8Bs31L5I0Kah .image-shape .label,#mermaid-svg-niSI8Bs31L5I0Kah .icon-shape .label{text-align:center;}#mermaid-svg-niSI8Bs31L5I0Kah .node.clickable{cursor:pointer;}#mermaid-svg-niSI8Bs31L5I0Kah .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-niSI8Bs31L5I0Kah .arrowheadPath{fill:#333333;}#mermaid-svg-niSI8Bs31L5I0Kah .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-niSI8Bs31L5I0Kah .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-niSI8Bs31L5I0Kah .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-niSI8Bs31L5I0Kah .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-niSI8Bs31L5I0Kah .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-niSI8Bs31L5I0Kah .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-niSI8Bs31L5I0Kah .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-niSI8Bs31L5I0Kah .cluster text{fill:#333;}#mermaid-svg-niSI8Bs31L5I0Kah .cluster span{color:#333;}#mermaid-svg-niSI8Bs31L5I0Kah div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-niSI8Bs31L5I0Kah .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-niSI8Bs31L5I0Kah rect.text{fill:none;stroke-width:0;}#mermaid-svg-niSI8Bs31L5I0Kah .icon-shape,#mermaid-svg-niSI8Bs31L5I0Kah .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-niSI8Bs31L5I0Kah .icon-shape p,#mermaid-svg-niSI8Bs31L5I0Kah .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-niSI8Bs31L5I0Kah .icon-shape .label rect,#mermaid-svg-niSI8Bs31L5I0Kah .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-niSI8Bs31L5I0Kah .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-niSI8Bs31L5I0Kah .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-niSI8Bs31L5I0Kah :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 分段函数图像
x ≤ 15: y = 4x/3
斜率: 4/3 ≈ 1.333
x > 15: y = 2.5x - 17.5
斜率: 2.5
边界点 x=15
y = 20 (两段连续)
关键特征
• 分段线性函数
• 在 x=15 处连续
• 超额累进计费
图2:分段函数特性图 - 展示了函数的数学特性和边界条件。
边界点 x = 15 的处理需要特别注意:
-
数学连续性:将 x = 15 代入两个公式:
- 第一段:
y = 4×15/3 = 60/3 = 20 - 第二段:
y = 2.5×15 - 17.5 = 37.5 - 17.5 = 20 - 两个结果相同,说明函数在 x=15 处连续,没有跳跃
- 第一段:
-
编程实现 :在代码中可以使用
if (x <= 15)或if (x < 15)配合 else 处理。题目要求「当 x 不超过 15 吨时」用第一个公式,因此使用x <= 15更符合题意,也能正确处理 x=15 的情况。
3. 浮点数精度注意事项
由于涉及浮点数运算,需要注意:
-
数据类型选择 :使用
double而非float,double提供更高的精度(约15-16位有效数字),能更好地满足「精确到小数点后2位」的要求。 -
运算顺序 :表达式
4 * x / 3在计算机中按从左到右计算,4 * x先得到浮点数结果,再除以3,避免了整数除法的精度损失。 -
比较操作 :浮点数的相等比较 (
==) 可能因精度问题不可靠,但本题中x <= 15的比较是安全的,因为15是精确的整数值。
4. 输出格式化要求
题目要求「精确到小数点后2位」,在C语言中:
-
格式说明符 :使用
printf("%.2f\n", y)实现%.2f表示输出浮点数,保留两位小数- 会自动进行四舍五入到指定小数位
-
四舍五入规则 :C语言的
printf使用「银行家舍入法」(round half to even),但对于大多数教学题目,可以理解为普通的四舍五入。
5. 输入验证考虑
虽然题目明确说明输入是「非负实数」,但在实际编程中可以考虑:
- 如果输入负数,程序仍会计算,但结果可能无实际意义
- 更健壮的实现可以添加输入验证,但本题未作要求
总结
本题的解题思路清晰:读取浮点数 → 判断分段条件 → 计算对应公式 → 格式化输出。关键在于理解分段函数的数学定义、正确处理边界条件、选择合适的数据类型和输出格式。
可视化总结
函数图像示意
#mermaid-svg-0T2ofjoXyEAvvkuT{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0T2ofjoXyEAvvkuT .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0T2ofjoXyEAvvkuT .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0T2ofjoXyEAvvkuT .error-icon{fill:#552222;}#mermaid-svg-0T2ofjoXyEAvvkuT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0T2ofjoXyEAvvkuT .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0T2ofjoXyEAvvkuT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0T2ofjoXyEAvvkuT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0T2ofjoXyEAvvkuT .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0T2ofjoXyEAvvkuT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0T2ofjoXyEAvvkuT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0T2ofjoXyEAvvkuT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0T2ofjoXyEAvvkuT .marker.cross{stroke:#333333;}#mermaid-svg-0T2ofjoXyEAvvkuT svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0T2ofjoXyEAvvkuT p{margin:0;}#mermaid-svg-0T2ofjoXyEAvvkuT :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 水费计算函数 y = f(x) 051015202530 用水量 x (吨) 7065605550454035302520151050 水费 y (元)
图3:水费计算函数曲线 - 展示了用水量与水费的对应关系,可以清晰看到:
- 在 x ≤ 15 时,函数斜率较小(约1.333),水费增长较缓
- 在 x > 15 时,函数斜率增大到2.5,水费增长加快
- 在 x=15 处函数连续,没有跳跃
数据计算示例表
| 用水量 x (吨) | 适用公式 | 计算过程 | 水费 y (元) |
|---|---|---|---|
| 0 | y = 4x/3 | 4×0/3 = 0 | 0.00 |
| 10 | y = 4x/3 | 4×10/3 ≈ 13.333 | 13.33 |
| 15 | y = 4x/3 | 4×15/3 = 20 | 20.00 |
| 16 | y = 2.5x-17.5 | 2.5×16-17.5 = 22.5 | 22.50 |
| 20 | y = 2.5x-17.5 | 2.5×20-17.5 = 32.5 | 32.50 |
| 30 | y = 2.5x-17.5 | 2.5×30-17.5 = 57.5 | 57.50 |
代码部分实现
c
#include <stdio.h>
int main(void)
{
double x, y; // 定义双精度浮点数变量 x(用水量)和 y(水费)
scanf("%lf", &x); // 从标准输入读取一个双精度浮点数到变量 x
if (x <= 15) { // 判断用水量是否不超过 15 吨
y = 4 * x / 3; // 使用第一段公式计算水费:y = 4x / 3
} else { // 否则(用水量超过 15 吨)
y = 2.5 * x - 17.5; // 使用第二段公式计算水费:y = 2.5x - 17.5
}
printf("%.2f\n", y); // 输出水费 y,保留两位小数
return 0; // 程序正常结束
}