题目链接
题目描述
计算 a+b
,处理多组测试数据,直到输入的两个整数均为 0 时结束。
输入描述:
输入包含多行,每行包含两个整数 a
和 b
。当读到 a
和 b
均为 0 的那一行时,输入结束,且该行数据不作处理。
输出描述:
对于每一组有效的 a
和 b
,都在单独的一行中输出它们的和。
解题思路
本题的核心是处理一种非常经典的多组输入模式:循环读取,直到遇到特定的"哨兵"值(sentinel value)。这里的哨兵就是 a=0
且 b=0
。
与上一题明确告知组数 t
不同,这里的循环次数是未知的。我们需要构建一个可以无限循环的结构,并在循环内部设置一个"出口"。
- 设置无限循环:使用
while(true)
或类似的结构创建一个可以持续执行的循环。 - 在循环内读取输入:在每次循环开始时,读取新的一行数据,得到
a
和b
。 - 检查结束条件:读取到
a
和b
之后,立刻检查它们是否同时为 0。- 如果
a == 0 && b == 0
这个条件成立,说明遇到了结束标志,此时应使用break
语句跳出整个循环。
- 如果
- 处理数据:如果未满足结束条件,则说明这是有效的数据。计算
a + b
的和,并将其输出。 - 循环继续:程序会回到循环的开头,继续读取下一行数据,重复上述过程。
这种 "先读取,后判断" 的 while-break
结构是处理此类问题的标准和健壮模式。
代码
#include <iostream>
using namespace std;
int main() {
long long a, b;
// 每次循环先读取a和b,如果读取成功,则进入循环体
while (cin >> a >> b) {
// 检查是否为结束标志
if (a == 0 && b == 0) {
break; // 跳出循环
}
// 如果不是结束标志,则计算并输出
cout << a + b << endl;
}
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 只要还有输入,就继续循环
while (sc.hasNextInt()) {
int a = sc.nextInt();
int b = sc.nextInt();
// 检查是否为结束标志
if (a == 0 && b == 0) {
break; // 跳出循环
}
// 如果不是结束标志,则计算并输出
System.out.println(a + b);
}
}
}
# 使用无限循环
while True:
try:
a, b = map(int, input().split())
# 检查是否为结束标志
if a == 0 and b == 0:
break # 跳出循环
# 如果不是,则计算并输出
print(a + b)
except (EOFError, ValueError):
# 处理可能的输入结束或空行,正常退出
break
算法及复杂度
- 算法:循环处理,哨兵值判断。
- 时间复杂度:
- 其中
N
是在遇到结束标志前的数据组数。 - 空间复杂度:
- 仅需常数空间存储变量。