背景:
input()
在 ACM 编程中的底层调用原理
1. input()
的核心原理
- 在 Python 中,
input()
的底层实现依赖于标准输入流sys.stdin
。 - 每次调用
input()
时,Python 会从sys.stdin
中读取一行字符串,直到遇到换行符\n
或文件结束符(EOF)。 - 读取的数据会以字符串形式返回,并自动去掉行末的换行符。
2. 输入在 ACM 编程中的特点
- 在 ACM 比赛中,输入通常是标准输入形式(例如,通过
stdin
提供一个多行文本流)。 - Python 的
input()
会逐行读取这些数据,因此与每次调用input()
配合使用,可以逐步解析多行输入。
3. 如何处理输入结束
- 在竞赛中,输入结束通常通过以下方式实现:
- 文件结束符(EOF):例如在本地测试中可以通过
Ctrl+D
(Linux/Mac)或Ctrl+Z
(Windows)模拟输入结束。 - 固定输入行数:通过第一行的数字
n
确定后续输入的行数。
- 文件结束符(EOF):例如在本地测试中可以通过
- 当
input()
遇到 EOF 时,会抛出EOFError
异常,可以通过try-except
捕获并处理。
另一种读入方式是:
import sys
input = sys.stdin.read # 读取所有输入
data = input().splitlines() # 按行分割
print(data)
1.
输入形式:
输入是一系列的a和b对(字符串),通过空格隔开。一对a和b占一行:
while True:
try:
s = input().split(' ')
a, b = int(s[0]), int(s[1])
print(a + b)
except EOFError:
break
2.
输入形式:
输入是一中复合信息,第一行表示总共有多少行输入,后面跟实际输入:
def calculate(s):
return int(s[0]) + int(s[1])
while True:
try:
n = int(input())
for i in range(n):
s = input()
s = s.split(' ')
print(calculate(s))
except EOFError:
break
3.
输入形式:
有一个终止判断的输入形式
while True:
try:
s = input()
num = s.split(' ')
res = int(num[0]) + int(num[1])
if s != '0 0':
print(res)
except EOFError:
break
4.
输入形式:
一个长的字符串,有一部分需要,一部分不重要。使用map函数进行整体数据类型的变化(重要)。
while True:
nums = input().split()
if int(nums[0]) == 0:
break
nums = list(map(int, nums[1:]))
ans = sum(nums)
print(ans)
5.
输入形式:
不同输入形式,输出要求包含空行隔断。
while True:
try:
a, b = input().split(' ')
print(int(a) + int(b), end='\n\n')
except Exception:
break
6.
输入形式:
最后一行不要换行,因此第一个输入是有用的,使用第一个input的信息进行循环。
1. input()
是逐行读取的
input()
是 Python 的内置函数,用于从标准输入中读取一行文本。每次调用input()
,它会等待用户输入一行文本并按下回车后返回该行的内容。- 在这段代码中,
n = int(input())
只读取第一行输入,不会影响后续的输入数据。后续的input()
调用会依次读取剩下的每一行。
2. 每次 input()
独立处理一行
- 在
for i in range(n)
中,input()
会独立读取每一行数据,并将其作为当前循环的输入。 - 因此,即使后续输入中包含多组数据,也不会干扰
n
的值或控制循环次数。
while True:
try:
n = int(input())
for i in range(n):
nums = list(map(int, input().split(' ')))
print(sum(nums[1:]))
if i != n - 1:
print()
except Exception:
break
7.
输入形式:
需要使用字典维护输入字符串
gpa_map = {
'A': 4,
'B': 3,
'C': 2,
'D': 1,
'F': 0,
}
while True:
try:
input_grade = input().split(' ')
sum_grade = 0
valid = True
for grade in input_grade:
if grade in gpa_map:
sum_grade += gpa_map[grade]
else:
print('Unknown')
valid = False
break
if valid:
print("{:.2f}".format(sum_grade/len(input_grade)))
except EOFError:
break
格式化函数:
数字 | 格式 | 输出 | 描述 |
---|---|---|---|
3.1415926 | {:.2f} | 3.14 | 保留小数点后两位 |
3.1415926 | {:+.2f} | +3.14 | 带符号保留小数点后两位 |
-1 | {:-.2f} | -1.00 | 带符号保留小数点后两位 |
2.71828 | {:.0f} | 3 | 不带小数 |
5 | {:0>2d} | 05 | 数字补零 (填充左边, 宽度为2) |
5 | {:x<4d} | 5xxx | 数字补x (填充右边, 宽度为4) |
10 | {:x<4d} | 10xx | 数字补x (填充右边, 宽度为4) |
1000000 | {:,} | 1,000,000 | 以逗号分隔的数字格式 |
0.25 | {:.2%} | 25.00% | 百分比格式 |
1000000000 | {:.2e} | 1.00e+09 | 指数记法 |
13 | {:>10d} | 13 | 右对齐 (默认, 宽度为10) |
13 | {:<10d} | 13 | 左对齐 (宽度为10) |
13 | {:^10d} | 13 | 中间对齐 (宽度为10) |
11 | '{:b}'.format(11) '{:d}'.format(11) '{:o}'.format(11) '{:x}'.format(11) '{:#x}'.format(11) '{:#X}'.format(11) |
1011 11 13 b 0xb 0XB |
进制 |
8.
输入形式:
分行式的多组测试样例,先用sys.stdin.read + input().splitlines() 看一下整体输入,然后根据题意答题
import sys
def mean(s):
return sum(s) / len(s)
while True:
try:
heap_num = int(input())
heap_list = list(map(int, input().split(' ')))
ave_height = mean(heap_list)
move = 0
for i in range(len(heap_list)):
if heap_list[i] - ave_height > 0:
move += heap_list[i] - ave_height
print(int(move))
print()
except EOFError:
break
9.
输入形式:
字符串输入转整型判断
while True:
try:
s = input()
# print(s)
res = 0
for i in s:
if int(i) % 2 == 0:
res += int(i)
print(res, end='\n\n')
except EOFError:
break
10.
输入形式:
本题开始稍加一点难度,主要是展示使用函数对象入门
def calculate(m, k):
if k:
bonus = m // k
if bonus or m - (bonus * k) + bonus > k:
bonus += calculate(m % k + bonus, k)
return bonus
else:
return 0
while True:
try:
m, k = list(map(int, input().split(' ')))
if m == 0 and k == 0:
break
res = m + calculate(m, k)
print(res)
except EOFError:
break
11. 共同祖先
输入形式:
输入作为字典键值对录入
def find_ansester(i, family_dict):
gen = 0
while i:
i = family_dict.get(i, '')
if i != '':
gen += 1
return gen
def find_relation(a, b, family_dict):
a_gen = find_ansester(a, family_dict)
b_gen = find_ansester(b, family_dict)
# print(a_gen, b_gen)
if a_gen > b_gen:
print('You are my elder')
elif a_gen < b_gen:
print('You are my younger')
else:
print('You are my brother')
while True:
try:
generation = int(input())
family_dict = dict()
for i in range(generation):
son, dad = list(map(int, input().split(' ')))
family_dict[son] = dad
find_relation(1, 2, family_dict)
except EOFError:
break
12. 打印数字图形
输入描述:
简单输入,模拟类题目,直接暴力
while True:
try:
n = int(input())
for i in range(1, n + 1):
left = [' '] * (n - i) + [str(j) for j in range(1, i + 1)]
tmp = left[:-1]
right = tmp[::-1]
right = [ele.replace(' ', '') for ele in right]
s = left + right
print(''.join(s))
for i in range(n - 1, 0, -1):
left = [' '] * (n - i) + [str(j) for j in range(1, i + 1)]
tmp = left[:-1]
right = tmp[::-1]
right = [ele.replace(' ', '') for ele in right]
s = left + right
print(''.join(s))
except EOFError:
break
13. 镂空三角形
输入形式:
有终止符号,注意判断。模拟类问题
while True:
try:
## 每一行实际数量是 i * 2 - 1 行前空格数是n - i
line = input().split()
if line[0] == '@':
break
n = int(line[1])
pattern = line[0]
for i in range(1, n + 1):
if i < n:
t = [' '] * (n - i)
new_s = list()
for idx in range(i * 2 - 1):
if idx == 0 or idx == i * 2 - 2:
new_s.append(pattern)
else:
new_s.append(' ')
row = t + new_s
else:
row = [pattern] * (i * 2 - 1)
print(''.join(row))
print()
except EOFError:
break