PIO4. 多组 A+B(T 组形式)
题目描述
给定 T 组测试数据,每组包含两个整数 a 和 b,请你分别求出 a + b。
输入格式
第一行一个整数 T,代表测试数据组数。 接下来 T 行,每行两个整数 a 和 b。
输出格式
输出 T 行,每行一个整数,代表对应组的 a + b。
示例
示例 1
输入:
3
1 2
114 514
2024 727
输出:
3
628
2751
说明: 三组数据分别是 1+2=3、114+514=628、2024+727=2751。
解题思路
第一步:理解问题本质
「T 组形式」是 ACM 输入里最常见的结构之一:第一行先告诉你有多少组, 后面每一组的格式都一样。读输入的节奏就是「先读 T,再循环 T 次」。
第二步:逐行读的写法
最直观的写法是逐行读:
t = int(input())
for _ in range(t):
a, b = map(int, input().split())
print(a + b)
它是对的,但当 T 很大时,每一次 input() 都涉及一次系统调用,
在 Python 里累积起来会明显变慢。
第三步:一次性读入(推荐)
更快的做法是把整段输入一次性读成 token 列表,再用一个下标 idx 往后推进:
data = sys.stdin.read().split()
split() 会自动按任意空白(空格、换行)切分,所以 3\n1 2\n114 514 会变成
["3", "1", "2", "114", "514", ...]。之后每读一个数就 idx += 1,
逻辑清晰,也避免了几万次函数调用。
完整代码实现
算法可视化 · 逐帧回放这道题的代码24 帧 · 录制输入
import sys
def solve() -> None:
"""读取 T 组 a b,逐行输出 a + b"""
data = sys.stdin.read().split()
if not data:
return
idx = 0
t = int(data[idx])
idx += 1
out = []
for _ in range(t):
a = int(data[idx])
b = int(data[idx + 1])
idx += 2
out.append(str(a + b))
sys.stdout.write("\n".join(out) + "\n")
if __name__ == "__main__":
solve()
示例推演
以样例输入为例,data 变成 ["3", "1", "2", "114", "514", "2024", "727"]:
| 步骤 | idx 指向 | 读到的值 | 计算 | 输出 |
|---|---|---|---|---|
| 读 T | 0 | 3 | — | — |
| 第 1 组 | 1, 2 | 1, 2 | 1 + 2 | 3 |
| 第 2 组 | 3, 4 | 114, 514 | 114 + 514 | 628 |
| 第 3 组 | 5, 6 | 2024, 727 | 2024 + 727 | 2751 |
最终逐行输出 3、628、2751。
复杂度分析
| 解法 | 时间复杂度 | 空间复杂度 | 说明 |
|---|---|---|---|
| 逐行读 | O(T) | O(1) | 直观,但每次 input() 有固定开销 |
| 一次性读入 | O(总字符数) | O(总字符数) | 推荐,I/O 开销最小 |
T 为测试数据组数;空间不计输出。
易错点总结
1. 忘记先读 T
有的人直接把所有 token 两两读成 a b,结果第一组的「a」其实是 T。
务必把第一行的 T 单独读出来。
2. 输出末尾多一个空行
如果先 print() 多次,每行末尾自带换行,没有问题;
若拼成一个字符串再用 sys.stdout.write 输出,记得补末尾 \n,
且不要在最后再空一行。
3. 没有 import sys
input() 是内置函数无需导入,但用 sys.stdin.read() 时必须 import sys。
扩展思考
- 如果题目改成「读到 EOF 为止」(没有 T),把
for _ in range(t)换成while idx + 1 < len(data)即可。 - 如果每组的数据个数不固定(先给 n 再给 n 个数),模式完全一样: 先读 n,再读 n 个数。