核心知识点
-
input()
vssys.stdin.readline()
input()
: 内置函数,使用方便,但速度较慢。它会读取一行,去除末尾的换行符\n
,并返回一个字符串。sys.stdin.readline()
: 速度更快,因为它使用了缓冲区。它会读取一行,但保留末尾的换行符\n
。因此,通常需要配合.strip()
或.rstrip()
使用。
-
print()
vssys.stdout.write()
print()
: 内置函数,功能强大,可以自动在末尾添加换行符,但相对较慢。sys.stdout.write()
: 速度更快,但只接受字符串作为参数,且不会自动添加换行符,需要手动添加'\n'
。
对于追求极致性能的竞赛,推荐使用 sys
模块。
import sys
# 之后就可以使用 sys.stdin.readline() 和 sys.stdout.write()
一、 输入 (Input)
场景1:读取单行数据
1.1 读取一个字符串
# 方法一:使用 input() (方便,但稍慢)
s = input()
# 示例输入: hello world
# s 的值: 'hello world'
# 方法二:使用 sys.stdin.readline() (推荐,更快)
import sys
s = sys.stdin.readline().strip() # .strip() 去除首尾空白,包括换行符
# 示例输入: hello world
# s 的值: 'hello world'
1.2 读取一个整数或浮点数
# 方法一:使用 input()
n = int(input())
f = float(input())
# 方法二:使用 sys.stdin.readline() (推荐)
import sys
n = int(sys.stdin.readline())
f = float(sys.stdin.readline())
场景2:读取单行内的多个值
这是最常见的场景之一,一行中有多个由空格隔开的数字或字符串。
# 示例输入: 10 20
# 示例输入: apple banana orange
# 方法一:使用 input().split()
import sys
# 读取两个整数
a_str, b_str = input().split()
a, b = int(a_str), int(b_str)
# 更简洁的写法:使用 map()
a, b = map(int, input().split())
# a 的值: 10, b 的值: 20
# 读取一个整数和一个字符串
n, s = input().split()
n = int(n)
# 方法二:使用 sys.stdin.readline().split() (推荐)
a, b = map(int, sys.stdin.readline().split())
# 读取一个列表
# 示例输入: 1 2 3 4 5
nums_str = input().split() # ['1', '2', '3', '4', '5']
nums = [int(x) for x in nums_str] # [1, 2, 3, 4, 5]
# 更简洁的写法
nums = list(map(int, input().split()))
# 或者使用 sys.stdin.readline()
nums = list(map(int, sys.stdin.readline().split()))
场景3:读取固定行数的多行数据
通常第一行会给出一个整数 N
,表示接下来有 N
行数据。
3.1 每行只有一个数据
# 示例输入:
# 3
# apple
# banana
# orange
import sys
# 读取行数
n = int(sys.stdin.readline())
# 循环读取N行
data = []
for _ in range(n):
line = sys.stdin.readline().strip()
data.append(line)
# data 的值: ['apple', 'banana', 'orange']
# 也可以用列表推导式,更简洁
# n = int(sys.stdin.readline())
# data = [sys.stdin.readline().strip() for _ in range(n)]
3.2 每行有多个数据
# 示例输入:
# 3
# 1 2
# 3 4
# 5 6
import sys
n = int(sys.stdin.readline())
matrix = []
for _ in range(n):
row = list(map(int, sys.stdin.readline().split()))
matrix.append(row)
# matrix 的值: [[1, 2], [3, 4], [5, 6]]
# 列表推导式写法
# n = int(sys.stdin.readline())
# matrix = [list(map(int, sys.stdin.readline().split())) for _ in range(n)]
场景4:读取不定行数的数据,直到文件末尾 (EOF)
这种场景下,输入没有明确的结束标志,需要一直读取直到输入流结束。
4.1 方法一:使用 try-except
(适用于 input()
和 sys.stdin.readline()
)
当 input()
或 sys.stdin.readline()
读到文件末尾时,会引发 EOFError
或返回一个空字符串。
import sys
lines = []
while True:
try:
line = sys.stdin.readline().strip()
if not line: # 如果是空行或文件末尾,则跳出
break
# 处理 line
# 例如,将一行数字存入列表
nums = list(map(int, line.split()))
lines.append(nums)
except EOFError:
break
# 之后处理 lines
4.2 方法二:直接遍历 sys.stdin
sys.stdin
本身就是一个可迭代对象,当输入结束时,循环会自动停止。
import sys
for line in sys.stdin:
# line 包含了末尾的 '\n',通常需要处理
line = line.strip()
if not line: # 有时需要处理空行
continue
# 处理 line
a, b = map(int, line.split())
# ... 进行计算和输出 ...
场景5:复杂的多组测试数据
题目通常会先给一个测试组数 T
,然后循环 T
次处理每一组数据。
# 示例输入:
# 2
# 3
# 1 2 3
# 4
# 10 20 30 40
import sys
# 读取测试组数 T
try:
t = int(sys.stdin.readline())
except (ValueError, IndexError): # 预防空输入
t = 0
for _ in range(t):
# --- 开始处理一组测试数据 ---
# 读取该组数据的行数 N
n = int(sys.stdin.readline())
# 读取该组数据的具体内容
nums = list(map(int, sys.stdin.readline().split()))
# 在这里进行计算
result = sum(nums)
# 输出该组数据的结果
print(result)
二、 输出 (Output)
场景1:输出单个值
# 方法一:使用 print() (最常用)
result = 100
print(result) # 自动换行
# 方法二:使用 sys.stdout.write() (更快)
import sys
result = 100
# 必须转换为字符串,且手动添加换行符
sys.stdout.write(str(result) + '\n')
场景2:在一行输出多个值,用空格隔开
# 示例:输出一个列表 [1, 2, 3, 4] 为 1 2 3 4
data = [1, 2, 3, 4]
# 方法一:使用 print() 的 * 解包
print(*data) # *data 会将列表解包成 print(1, 2, 3, 4)
# 方法二:使用 str.join() (推荐,非常高效)
# 注意:join() 的元素必须是字符串,所以要用 map(str, ...)
print(' '.join(map(str, data)))
# 方法三:使用循环和 print() 的 end 参数
for i, item in enumerate(data):
# print(item, end=' ' if i < len(data) - 1 else '')
print(item, end=' ')
print() # 最后输出一个换行符来结束这一行
# 方法四:使用 sys.stdout.write() 和 join()
import sys
sys.stdout.write(' '.join(map(str, data)) + '\n')
场景3:格式化输出
3.1 使用 f-string
f-string 是目前最现代、最易读的格式化方法。
name = "Alice"
score = 95.5
print(f"Name: {name}, Score: {score}")
# 控制浮点数精度 (例如,保留两位小数)
pi = 3.1415926
print(f"{pi:.2f}") # 输出: 3.14
3.2 使用 str.format()
方法
name = "Bob"
score = 88.0
print("Name: {}, Score: {}".format(name, score))
# 控制浮点数精度
pi = 3.1415926
print("{:.2f}".format(pi)) # 输出: 3.14
三、完整 ACM 模式模板
import sys
def solve():
# 读取单行输入
# n, k = map(int, sys.stdin.readline().strip().split())
# 读取数组
# arr = list(map(int, sys.stdin.readline().strip().split()))
# 在这里编写核心解题逻辑
# ...
# 构造结果
result = "your_answer"
# 输出结果
sys.stdout.write(str(result) + '\n')
def main():
# 处理单组测试数据
# solve()
# 处理多组测试数据
try:
# 尝试读取测试组数 T
t = int(sys.stdin.readline())
except (ValueError, IndexError):
# 如果读取失败(例如输入为空),则默认为1组或0组
t = 1 # 或者 t = 0
for _ in range(t):
solve()
if __name__ == "__main__":
main()
总结
操作 | 方便但慢 (小数据量) | 高效推荐 (大数据量) |
---|---|---|
读一行 | s = input() | s = sys.stdin.readline().strip() |
读整数 | n = int(input()) | n = int(sys.stdin.readline()) |
读一行多个数 | arr = list(map(int, input().split())) | arr = list(map(int, sys.stdin.readline().split())) |
读到EOF | try-except 块 | for line in sys.stdin: |
输出 | print(var) | sys.stdout.write(str(var) + '\n') |
输出列表 | print(*my_list) | sys.stdout.write(' '.join(map(str, my_list)) + '\n') |
始终优先使用 sys.stdin.readline()
,并记得用 .strip()
或 .rstrip()
去掉换行符。