PIO14. 单组 保留小数位数
题目描述
给定一个小数 x,请你保留 3 位小数后输出。 如果原来的小数位数少于 3 位,需要补 0; 如果多于 3 位,需要四舍五入到 3 位。
输入格式
第一行有一个小数 x。
输出格式
输出一个小数,保留 3 位。
示例
示例 1
输入:
1.23
输出:
1.230
说明: 小数位数少于 3 位,末尾补 0。
示例 2
输入:
114.514
输出:
114.514
说明: 恰好 3 位,原样输出。
示例 3
输入:
123
输出:
123.000
说明: 整数没有小数部分,补足 3 个 0。
解题思路
第一步:理解问题本质
「保留 k 位小数」包含三件事:四舍五入、不足补零、统一位数。 三者缺一不可,手动用字符串处理会写出很多分支。
第二步:手动字符串处理(不推荐)
如果当成字符串做,至少要考虑:
- 没有小数点(
123)→ 补.000 - 小数部分不足 3 位(
1.23)→ 补0 - 小数部分超过 3 位(
3.14159)→ 截断并考虑进位
…9999 这种还会发生连锁进位(0.9999 → 1.000),手写极易出错。
第三步:交给格式化输出(最优)
Python 的格式化字符串一步到位:
f"{x:.3f}"
:.3f 表示「定点数、保留 3 位小数」,Python 会自动四舍五入并补齐位数。
把 3 换成变量 k 就是 f"{x:.{k}f}",位数也可以动态控制。
完整代码实现
本题无可视化步骤:代码里没有可逐帧展示的过程(执行轨迹已经录下来, 但局部变量里找不到推进中的中间状态 —— 比如全篇就是一次正则替换或一次切片)。
import sys
def solve() -> None:
"""读取一个小数,保留 3 位小数输出"""
line = sys.stdin.readline().split()
if not line:
return
x = float(line[0])
# 正常只有一个小数;若输入额外给出位数 k,则按 k 保留(兼容变体数据)
k = int(line[1]) if len(line) > 1 else 3
sys.stdout.write(f"{x:.{k}f}\n")
if __name__ == "__main__":
solve()
示例推演
| 输入 | 转成 float | f"{x:.3f}" 结果 |
|---|---|---|
1.23 | 1.23 | 1.230 |
114.514 | 114.514 | 114.514 |
123 | 123.0 | 123.000 |
3.14159 | 3.14159 | 3.142(四舍五入) |
复杂度分析
| 解法 | 时间复杂度 | 空间复杂度 | 说明 |
|---|---|---|---|
| 手动字符串处理 | O(len) | O(len) | 分支多、易错 |
| 格式化输出 | O(1) | O(1) | 推荐,一步到位 |
易错点总结
1. 用整数解析输入
int("1.23") 会直接报错。小数必须用 float 解析。
2. 手动补零漏掉整数情况
123 没有小数点,s.split(".") 只会得到一个元素,
直接取 [1] 会越界。用格式化输出就不会有这个问题。
3. printf 风格写错
在 Python 里应写 f"{x:.3f}",而不是 C 的 "%.3f" % x
(后者也能用,但不如 f-string 直观)。
扩展思考
- 要「保留 3 位有效数字」(而不是小数位)应写成
f"{x:.3g}",含义不同。 - 浮点数存在精度误差,比如
0.1 + 0.2 != 0.3; 竞赛中若要求精确小数,可考虑用decimal.Decimal或整数运算。