1. 从LeetCode到ACM:为什么IO处理是竞赛的第一道坎
很多朋友都是从LeetCode开始刷题的,习惯了那种“核心代码模式”——系统已经把输入数据准备好了,你只需要写一个函数处理就行。但一到真正的算法竞赛或者大厂机试,切换到ACM模式,很多人就懵了。我第一次参加线上笔试时,就栽在了输入输出上,题目本身不难,但花了十几分钟调试怎么读数据,最后时间不够,那种感觉真的挺憋屈的。
ACM模式到底有什么不同?简单说,它要求你自己处理所有的输入和输出。题目不会给你一个现成的函数参数,而是通过标准输入(stdin)给你一堆数据,你需要从这些数据里解析出有用的信息,计算完结果后,再通过标准输出(stdout)打印出去。听起来简单,但实际做起来,各种格式变化多端,一不小心就会读错数据,导致整个程序逻辑跑偏。
Python在这方面的优势很明显,代码简洁,处理字符串方便,但劣势也同样突出——速度慢。在数据量大的竞赛题里,一个低效的IO处理方式可能直接让你“时间超限”。我后来专门花时间研究了这个,发现优化好的和没优化的代码,执行时间能差好几倍。所以,今天我就把自己这些年踩过的坑、总结的技巧,从最基础的讲起,一直到竞赛级的优化方案,都分享给你。无论你是刚开始接触ACM模式,还是想进一步提升效率,相信都能找到有用的东西。
2. 基础不牢地动山摇:Python输入输出核心三剑客
想把ACM模式的输入玩转,你得先彻底搞懂三个最基础的函数:input()、split()和map()。它们就像三把钥匙,能打开绝大多数输入格式的大门。
input():它可不是直接给你数字。这是新手最容易误解的地方。input()永远返回一个字符串(str),哪怕你在控制台输入的是“123”,它拿到手的也是带引号的'123'。所以,你的第一反应就应该是:需要类型转换。多行输入怎么办?很简单,调用几次input()就读几行。比如第一行读个数n,后面要读n行数据,那就先n = int(input()),然后写个循环for _ in range(n): data = input()。
split():你的字符串切割器。input()读进来的经常是“1 2 3 4 5”这样用空格隔开的一串数。split()默认就按空白字符(空格、换行、制表符等)来切,把它变成列表['1', '2', '3', '4', '5']。如果题目是用逗号分隔的,比如“1,2,3”,那就用split(',')。这里有个细节,字符串首尾有时会有多余空格,保险起见可以先input().strip().split(),strip()能去掉两端的空白符。
map():批量类型转换的神器。现在你有了一个字符串列表['1', '2', '3'],需要变成整数[1, 2, 3]。你可以写列表推导式[int(x) for x in list],但更常见的写法是list(map(int, list))。map(int, list)的意思是对列表里每个元素应用int()函数,它返回一个“map对象”(迭代器),为了方便使用,我们再用list()把它转成列表。如果一行只有两个数,你可以直接a, b = map(int, input().split()),连列表都不需要,这叫序列解包,非常方便。
把这三个组合起来,就是最经典的单行整数输入套路:a, b, c = map(int, input().split())。如


888

被折叠的 条评论
为什么被折叠?



