python处理acm模式输入
你可以把 Python ACM 理解成对应这三类 C++:
scanf(...)
while (scanf(...) != EOF)
while (T--) { scanf(...) }
Python 里分别有很直接的写法。
1. 最基础:对应 scanf()
C++:
int a, b;
scanf("%d%d", &a, &b);
Python:
a, b = map(int, input().split())
如果是浮点数:
a, b = map(float, input().split())
如果是一整行数组:
C++:
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
Python 常见:
nums = list(map(int, input().split()))
例如输入:
1 2 3 4 5
得到:
nums = [1, 2, 3, 4, 5]
2. 推荐 ACM 模板:sys.stdin.readline
数据多的时候,建议:
import sys
input = sys.stdin.readline
之后还是照常写:
n = int(input())
a, b = map(int, input().split())
nums = list(map(int, input().split()))
你可以直接记一个基础模板:
import sys
input = sys.stdin.readline
n = int(input())
nums = list(map(int, input().split()))
print(nums)
3. 对应 while(scanf(...) != EOF)
C++:
int a, b;
while (scanf("%d%d", &a, &b) != EOF) {
printf("%d\n", a + b);
}
Python 最推荐:
import sys
for line in sys.stdin:
a, b = map(int, line.split())
print(a + b)
也就是:
while (scanf(...) != EOF)
对应:
for line in sys.stdin:
如果你更喜欢 while 风格,也可以:
import sys
while True:
line = sys.stdin.readline()
if not line:
break
a, b = map(int, line.split())
print(a + b)
因为:
sys.stdin.readline()
遇到 EOF 会返回:
""
所以:
if not line:
break
就相当于 C++ 的:
== EOF
4. 对应 while(T--)
C++:
int T;
scanf("%d", &T);
while (T--) {
int a, b;
scanf("%d%d", &a, &b);
printf("%d\n", a + b);
}
Python:
T = int(input())
for _ in range(T):
a, b = map(int, input().split())
print(a + b)
这个非常重要。
你可以直接对应记:
while (T--)
↓
for _ in range(T):
这里 _ 只是一个普通变量名,表示:
我只想循环 T 次,不关心当前是第几次。
5. 如果需要测试用例编号
C++:
for (int t = 1; t <= T; t++) {
printf("Case #%d: ", t);
}
Python:
for t in range(1, T + 1):
print(f"Case #{t}:")
例如:
T = int(input())
for t in range(1, T + 1):
a, b = map(int, input().split())
print(f"Case #{t}: {a + b}")
6. 常见输入类型
一个整数
n = int(input())
一个浮点数
x = float(input())
一行多个整数
a, b, c = map(int, input().split())
一行多个浮点数
a, b = map(float, input().split())
一行字符串
s = input().strip()
如果用了:
input = sys.stdin.readline
字符串经常建议 .strip(),因为 readline() 会保留 \n。
7. 一行数组
nums = list(map(int, input().split()))
例如:
5 8 2 10
得到:
[5, 8, 2, 10]
8. 输入 n 行二维数据
例如:
3
1 2
3 4
5 6
Python:
n = int(input())
q = []
for _ in range(n):
a, b = map(int, input().split())
q.append((a, b))
最后:
q
是:
[(1, 2), (3, 4), (5, 6)]
9. 输出
最普通:
print(ans)
输出多个值:
print(a, b)
默认中间加空格。
比如:
a = 3
b = 5
print(a, b)
输出:
3 5
10. 输出数组
这个很常用。
nums = [1, 2, 3, 4]
print(*nums)
输出:
1 2 3 4
这里 *nums 可以理解为把:
[1, 2, 3, 4]
拆成:
print(1, 2, 3, 4)
不要直接:
print(nums)
因为会输出:
[1, 2, 3, 4]
一般 ACM 格式不想要中括号。
11. 控制小数位数
C++:
printf("%.6lf\n", auc);
Python:
print(f"{auc:.6f}")
例如:
auc = 2 / 3
print(f"{auc:.6f}")
输出:
0.666667
12. 不换行输出
C++:
printf("%d ", x);
Python:
print(x, end=" ")
例如:
for x in [1, 2, 3]:
print(x, end=" ")
输出:
1 2 3
13. Python 自定义排序
这个很重要。
C++ 里你习惯:
sort(a.begin(), a.end(), cmp);
或者:
bool operator<(...) const
Python 最常用:
a.sort(key=...)
或者:
sorted(a, key=...)
区别:
a.sort()
直接修改原数组。
而:
b = sorted(a)
返回一个新数组,原来的 a 不变。
14. 默认升序
nums = [3, 1, 5, 2]
nums.sort()
print(nums)
得到:
[1, 2, 3, 5]
15. 降序
C++:
sort(a.begin(), a.end(), greater<int>());
Python:
nums.sort(reverse=True)
例如:
nums = [3, 1, 5, 2]
nums.sort(reverse=True)
print(nums)
得到:
[5, 3, 2, 1]
16. 按某一个字段排序
例如:
q = [
(0.9, 1),
(0.6, 0),
(0.8, 1)
]
按第一个元素 score:
q.sort(key=lambda x: x[0])
得到:
[
(0.6, 0),
(0.8, 1),
(0.9, 1)
]
这里:
lambda x: x[0]
可以理解成一个匿名函数:
def get_score(x):
return x[0]
所以:
q.sort(key=lambda x: x[0])
就是:
排序时,用
x[0]作为排序依据。
17. 按第二个字段排序
q.sort(key=lambda x: x[1])
18. 第一关键字升序,第二关键字升序
比如:
q = [
(2, 5),
(1, 3),
(2, 1),
(1, 7)
]
直接:
q.sort()
Python 的 tuple 默认就是:
先比较第一个,如果第一个一样,再比较第二个。
结果:
[
(1, 3),
(1, 7),
(2, 1),
(2, 5)
]
等价于:
q.sort(key=lambda x: (x[0], x[1]))
19. 第一关键字升序,第二关键字降序
这个特别常考。
C++ 可能写:
if (a.x != b.x) return a.x < b.x;
return a.y > b.y;
Python:
q.sort(key=lambda x: (x[0], -x[1]))
例如:
q = [
(1, 3),
(1, 7),
(2, 1),
(2, 5)
]
q.sort(key=lambda x: (x[0], -x[1]))
print(q)
得到:
[
(1, 7),
(1, 3),
(2, 5),
(2, 1)
]
因为:
-x[1]
越小,说明原来的 x[1] 越大。
20. 第一关键字降序,第二关键字升序
q.sort(key=lambda x: (-x[0], x[1]))
这个套路你可以直接记:
升序:x
降序:-x
适用于数字。
21. struct / class 自定义排序
如果你非要像 C++ 那样自己定义类,也可以。
class E:
def __init__(self, score, label):
self.score = score
self.label = label
然后:
q.sort(key=lambda x: x.score)
例如:
class E:
def __init__(self, score, label):
self.score = score
self.label = label
q = [
E(0.9, 1),
E(0.6, 0),
E(0.8, 1)
]
q.sort(key=lambda x: x.score)
这就对应你的 C++:
bool operator<(const E& e2) const {
return score < e2.score;
}
不过算法题里 Python 一般更喜欢:
tuple
或者:
list
而不是专门定义类。
22. 如果排序规则非常复杂
Python 也支持类似 C++ cmp 的比较函数:
from functools import cmp_to_key
比如:
from functools import cmp_to_key
def cmp(a, b):
if a[0] != b[0]:
return -1 if a[0] < b[0] else 1
return -1 if a[1] > b[1] else 1
q.sort(key=cmp_to_key(cmp))
但一般不推荐。
Python 排序优先考虑:
key=lambda ...
因为更简单、更快、更不容易写错。
你可以认为:
cmp
在 Python 里大多数时候应该改写成:
key
23. 你最该记住的一套
如果你已经很熟 C++ ACM,我建议 Python 先记这几个映射:
| C++ | Python |
|---|---|
scanf("%d",&n) |
n = int(input()) |
scanf("%d%d",&a,&b) |
a,b = map(int,input().split()) |
while(scanf(...) != EOF) |
for line in sys.stdin: |
while(T--) |
for _ in range(T): |
vector<int> |
list |
printf("%d\n",ans) |
print(ans) |
printf("%.6lf",x) |
print(f"{x:.6f}") |
sort(a.begin(),a.end()) |
a.sort() |
greater<int>() |
a.sort(reverse=True) |
自定义 cmp |
a.sort(key=lambda x: ...) |
你刷 Python ACM 的话,最实用的模板就是:
import sys
input = sys.stdin.readline
T = int(input())
for _ in range(T):
n = int(input())
nums = list(map(int, input().split()))
nums.sort()
print(*nums)
这已经能覆盖相当大一部分基础在线编程题了。

浙公网安备 33010602011771号