多组 A+B(零尾模式)
输入输出模拟约 993 字大约 3 分钟
PIO5. 多组 A+B(零尾模式)
题目描述
给定若干组测试数据,最后一组数据为 0 0,作为输入的结尾。
每组数据有两个整数 a 和 b,请你分别求出 a + b。
输入格式
每行有两个整数 a 和 b。
最后一行为 0 0,代表输入结束(这一组不是需要计算的数据)。
输出格式
输出若干行,每行一个整数,代表对应组的 a + b(不含结尾的 0 0)。
示例
示例 1
输入:
1 2
114 514
2024 727
0 0输出:
3
628
2751说明:
前三组正常计算;读到 0 0 时立即停止,因此只输出三行。
解题思路
第一步:理解问题本质
和「T 组形式」不同,这里事先不知道有几组数据,而是用一个哨兵值
(0 0)表示结束。这类题必须用循环,每读一组就判断一次:
「这一组是不是结束标记?」是就 break,否则才计算输出。
第二步:把哨兵当成普通数据会怎样
如果只写 for 循环而不知道次数,就要么漏读、要么把 0 0 也算成一组
(输出一个多余的 0)。所以关键是先把这一对读出来,再判断,
判断通过才计算。
第三步:一次性读入的写法
同样可以先把整段输入读成 token 列表,再用 i 两两推进:
# i + 1 < len(data) 保证还剩至少两个 token,否则凑不齐一组 a b
while i + 1 < len(data):
a, b = int(data[i]), int(data[i + 1])
# 这一对已经读完,先把游标挪两位,无论是否结尾都不会重复读
i += 2
# 两个都为 0 才算结尾;单独的 0 5 仍要按普通数据计算
if a == 0 and b == 0:
break
...注意循环条件是 i + 1 < len(data) —— 保证还能凑出一对数。
另外判断必须是 a == 0 and b == 0,不能只看其中一个:
题目只约定「两个都为 0 才是结尾」,单独的 0 5 仍然是合法数据。
完整代码实现
import sys
def solve() -> None:
"""读到 0 0 为止,逐行输出 a + b"""
data = sys.stdin.read().split()
out = []
i = 0
while i + 1 < len(data):
a = int(data[i])
b = int(data[i + 1])
i += 2
if a == 0 and b == 0: # 结束标记
break
out.append(str(a + b))
sys.stdout.write("\n".join(out) + "\n")
if __name__ == "__main__":
solve()示例推演
输入 token 序列为 1 2 114 514 2024 727 0 0:
| 轮次 | 读到的 a, b | 是否结束 | 输出 |
|---|---|---|---|
| 1 | 1, 2 | 否 | 3 |
| 2 | 114, 514 | 否 | 628 |
| 3 | 2024, 727 | 否 | 2751 |
| 4 | 0, 0 | 是 → break | — |
最终输出三行。
复杂度分析
| 解法 | 时间复杂度 | 空间复杂度 | 说明 |
|---|---|---|---|
| 逐行读 + break | O(T) | O(1) | 直观 |
| 一次性读入 | O(总字符数) | O(总字符数) | 推荐,I/O 更省 |
T 为实际需要计算的数据组数。
易错点总结
1. 把 0 0 也输出了
这是最常见的错误:先输出再判断。一定要先判断是否结束,
通过后才计算。
2. 只判断一个 0
a == 0 或 b == 0 都不够 —— 0 5 是合法数据,答案是 5。
必须是 a == 0 and b == 0。
3. 循环条件越界
用下标推进时,循环条件要写成 i + 1 < len(data);
若写成 i < len(data),最后一轮可能访问不到 data[i + 1]。
扩展思考
- 如果结束标记改成单独一行
0(只给一个数),循环就要改成一元判断。 - 「T 组形式」「零尾模式」「读到 EOF」是三种主流输入约定,
读输入的骨架不同,但处理单组数据的逻辑可以完全复用。