背景:
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:breaknums = 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 = 0valid = Truefor grade in input_grade:if grade in gpa_map:sum_grade += gpa_map[grade]else:print('Unknown')valid = Falsebreakif 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 sysdef 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 = 0for i in range(len(heap_list)):if heap_list[i] - ave_height > 0:move += heap_list[i] - ave_heightprint(int(move))print()except EOFError:break
9.
输入形式:
字符串输入转整型判断
while True:try:s = input()# print(s)res = 0for 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 bonuselse:return 0while True:try:m, k = list(map(int, input().split(' ')))if m == 0 and k == 0:breakres = m + calculate(m, k) print(res)except EOFError:break
11. 共同祖先
输入形式:
输入作为字典键值对录入
def find_ansester(i, family_dict):gen = 0while i:i = family_dict.get(i, '')if i != '':gen += 1return gendef 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] = dadfind_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 + rightprint(''.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 + rightprint(''.join(s))except EOFError:break
13. 镂空三角形
输入形式:
有终止符号,注意判断。模拟类问题
while True:try:## 每一行实际数量是 i * 2 - 1 行前空格数是n - iline = input().split()if line[0] == '@':breakn = 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_selse:row = [pattern] * (i * 2 - 1)print(''.join(row))print()except EOFError:break