ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

蓝桥杯Python组模板:从IO到DP的备赛速查与实战策略

蓝桥杯Python组模板:从IO到DP的备赛速查与实战策略 1. 为什么Python组更该有一套自己的模板蓝桥杯的Python组和C组最大的差别不是语言语法而是时间预算的分配方式。同样一道题C选手可能花十分钟敲完然后纠结边界Python选手往往要在敲之前就想清楚用什么容器、怎么读输入、会不会超时。这个差异决定了Python选手的模板不是“背代码”而是把那些确定不变的部分提前固化让赛场上只剩思考。我前后打过几场也带过学弟学妹备赛最大的感受是真正拉开差距的不是谁多会一个算法而是谁在开考后的前二十分钟没有被输入格式、递归深度、输出拼接这些杂事拖住。一套趁手的python蓝桥杯模板本质是把自己从重复劳动里赎出来把脑力留给建模和推导。这套东西适合谁打过一点算法题、知道01背包动态规划python怎么写、但一到比赛就手忙脚乱的选手也适合刚学完python入门内容、想试试水的新手。新手照着抄能拿住基础分老手把它当速查手册赛前扫一遍查漏补缺。下面我就按“地基—基础—进阶—策略—排查”的顺序把自己这些年攒下来的东西完整摊开讲一遍。1.1 Python组和C组的差异到底在哪先说清楚差距有多大才好判断模板该往哪个方向堆。同样的算法复杂度Python的执行速度大概只有C的十分之一到三十分之一具体倍数取决于循环里干了多少事。这意味着C选手敢写的 O(n²) 暴力n 到五千还行n 到两万就悬而Python里 n 到三千的 O(n²) 就已经接近一秒的边界了。但Python有两个C比不了的优势。第一是大整数原生支持题目里出现阶乘、2的幂次、超长整数运算时Python写起来几乎零成本C得手写高精度。第二是标准库极其丰富itertools、collections、heapq、bisect、datetime这些模块直接调用省下大量造轮子的时间。所以Python组的策略很明确能靠库解决的绝不手写能靠数学推导降复杂度的绝不上数据结构实在要写暴力就用库函数把常数压到最低。模板要围绕这三条来组织而不是把C的板子翻译一遍。1.2 模板不该是背诵材料而是“电路板”很多人对模板有误解觉得是把一堆代码存成文本比赛时复制粘贴。真到了赛场上你会发现题目条件千奇百怪直接粘贴的代码十有八九要改三四行改的过程反而更容易出错。我更愿意把模板理解成电路板每个模块只负责一件事接口清晰插上去就能用剩下的逻辑你自己接线。比如二分查找模板它不负责帮你判断该用左边界还是右边界那是你的活它只保证在数组有序的前提下返回第一个不小于 x 的位置且不会死循环。这个边界划清楚了模板才有复用的价值。按照这个思路我把模板分成三层第一层是IO与运行环境属于每道题都要用的地基第二层是数学和序列处理的基础件出现频率极高第三层是图论、动态规划这类成套算法属于需要整块调用的模块。三层分开管理赛前按层检查比重头背一遍效率高得多。1.3 备赛节奏与模板的分层策略备赛时间怎么切直接决定模板最终长什么样。我的建议是倒着来先明确比赛时长和题型分布再倒推需要哪些能力。通常填空题占一部分这部分对速度要求不高可以用暴力枚举甚至手算辅助模板需求集中在日期计算、进制转换、排列枚举上。编程题占大头难度分层明显前面的签到题基本是模拟加简单数学后面的压轴题才涉及图论和DP。所以模板的优先级排序应该是输入输出 数学工具 序列处理 搜索 图论 DP。按这个顺序投入时间收益是最高的。我见过不少人一上来就啃线段树和网络流结果比赛时连多组输入的结束条件都处理错白白丢分这个账算不过来。2. 环境与IO模板的地基这部分最不起眼却最容易翻车。很多人本地跑得好好的交上去全是运行错误八成问题出在这里。2.1 Python环境与IDE的配置要点先说python安装。蓝桥杯的评测机用的是官方指定的Python版本这几年基本是Python 3.8或更新的3.x版本具体以当年通知为准。你在本地准备环境时尽量对齐这个版本号别用太新的特性比如海象运算符在旧版本上会直接语法错误。安装的时候有一个坑必须提Windows下安装包默认不勾选“Add Python to PATH”不勾的话命令行里敲python会提示找不到命令。这个不是致命问题但对新手来说很折腾。安装完成后在命令行验证python --version和pip --version都能正常输出才算装好。编辑器方面pycharm配置python环境对新手最友好新建项目时选好解释器就完事代码补全和调试功能都很强。如果你习惯轻量一点的vscode python环境配置也不难装Python扩展按 CtrlShiftP 选解释器再配一个launch.json就能断点调试。我自己的习惯是赛前用PyCharm对着题目练因为它的调试器能直接看变量排查逻辑错误比print快得多。注意赛前一定要在本地完整模拟一次“新建文件—写代码—读输入文件—输出到控制台”的流程。有些评测机要求从标准输入读、标准输出写本地如果用文件读写测试容易忘记改回来。2.2 输入输出模板快读快写与结束符处理蓝桥杯如何读取输入python这个问题在搜索里出现频率极高说明踩坑的人多。核心结论只有一句优先用sys.stdin而不是input()。input()每次调用都要做一次字符串剥离和类型转换准备数据量大时开销很明显。十万行输入用input()可能要一秒多换成一次性读取再切分往往降到零点几秒。下面是我常用的两个版本。第一个版本适合单组数据、格式规范的题目import sys def main(): data sys.stdin.buffer.read().split() n int(data[0]) a list(map(int, data[1:1 n])) # 后续逻辑 print(sum(a)) if __name__ __main__: main()sys.stdin.buffer.read()返回字节串.split()按空白切分这样换行、空格、制表符、多余空行全部自动处理掉。这个写法几乎能应付九成的蓝桥杯题型。第二个版本适合多组数据、遇到终止条件才停的题目import sys def main(): for line in sys.stdin: line line.strip() if not line: continue n, m map(int, line.split()) if n 0 and m 0: break # 处理这一组 print(n m) if __name__ __main__: main()这里有两个细节值得说。一是strip()之后要判断空行因为有些题目最后会多一个空行不处理会报错。二是终止条件的判断要写在处理逻辑之前否则最后一组会多余输出一次。输出端也有讲究。多次print()会频繁触发写操作数据量大时改用拼接再一次性写出sys.stdout.write(\n.join(map(str, ans)) \n)注意这里手动补了个换行符因为很多评测机不介意行尾有没有换行但有些题目对输出格式敏感补上更保险。另外整数转字符串这一步用map(str, ...)交给内置函数比列表推导式快一些。2.3 递归深度、数据规模与耗时预估Python默认递归深度是一千层左右深搜稍微深一点就RecursionError。解决办法是在程序开头加一行import sys sys.setrecursionlimit(1 20)1 20是一百多万足够应付绝大多数搜索题。但要注意递归深度调大之后如果栈真的爆了程序可能直接崩溃而不是抛异常排查起来更难。我个人的经验是深度可能超过五万时就不要硬用递归了改成显式栈的迭代写法更稳。再说耗时预估这是决定要不要换算法的关键。下面这张表是我本地实测加比赛体感总结的供参考数据规模可接受的复杂度典型做法n ≤ 20O(2ⁿ)、O(n!)状压DP、全排列枚举n ≤ 100O(n³)Floyd、三重循环DPn ≤ 2000O(n²)二维DP、朴素匹配n ≤ 10⁵O(n log n)排序、二分、堆、树状数组n ≤ 10⁶O(n)前缀和、双指针、线性筛n ≥ 10⁷通常无解需要数学推导降维这张表的用法是读完题先估上界再对照表格选算法。如果发现上界落在红色区域说明暴力必挂得回去重新推公式或者找性质。我遇到过的典型场景是一道求区间内满足某种性质的数的个数直接枚举是 O(n)但 n 到了十的九次方最后是靠数位统计加前缀和降到了 O(log n)。提示本地测耗时别用time.time()粗略算用time.perf_counter()精度更高。测量时把输入读取也算进去因为那部分是真实开销。3. 高频基础模板把常用操作变成肌肉记忆基础模板的价值在于“不用想”。写的时候手指自动敲出来脑子全部留给题目逻辑。这一层我按数学、序列、字符串三块来整理。3.1 数学类模板质数、幂次与组合数先说最大公约数和最小公倍数。Python 3.9之后math.gcd和math.lcm都支持多参数直接调用即可。旧版本只有math.gcd最小公倍数要自己写from math import gcd def lcm(a, b): return a // gcd(a, b) * b注意这里先除后乘避免a*b溢出。虽然Python大整数不会溢出但早除可以减小中间结果的位数对速度有轻微好处。快速幂是另一个高频件。求 a 的 b 次方对 mod 取模标准写法是用二进制拆分def qpow(a, b, mod): r 1 a % mod while b: if b 1: r r * a % mod a a * a % mod b 1 return r循环次数是 b 的二进制位数b 到十的十八次方也只需要六十次循环。这个模板还经常被改造用来求逆元条件是 mod 为质数且 a 不是 mod 的倍数此时qpow(a, mod - 2, mod)就是 a 的乘法逆元。质数筛我更推荐线性筛虽然代码比埃氏筛长一点但复杂度是严格的 O(n)def linear_sieve(n): is_comp bytearray(n 1) primes [] for i in range(2, n 1): if not is_comp[i]: primes.append(i) for p in primes: if i * p n: break is_comp[i * p] 1 if i % p 0: break return primesbytearray用来做标记数组内存占用只有列表的八分之一左右n 到一千万也能扛住。这个筛法顺便还能求每个数的最小质因子改写一下就能做质因数分解模板。组合数方面小范围直接用递推n 到几千都够用MAXN 2005 C [[0] * MAXN for _ in range(MAXN)] for i in range(MAXN): C[i][0] 1 for j in range(1, i 1): C[i][j] (C[i - 1][j - 1] C[i - 1][j]) % MOD如果 n 很大但查询次数少用阶乘加逆元更快如果查询次数极多且模数固定可以预处理阶乘和逆元数组。这三种写法各有适用场景别只会一种。3.2 序列处理模板前缀和、差分与二分前缀和解决的是“区间求和”问题一维版本一眼就会真正容易写错的是二维版本n, m 5, 5 a [[0] * (m 1) for _ in range(n 1)] pre [[0] * (m 1) for _ in range(n 1)] for i in range(1, n 1): row pre[i] prev pre[i - 1] cur a[i] for j in range(1, m 1): row[j] prev[j] row[j - 1] - prev[j - 1] cur[j]查询子矩形 (x1,y1) 到 (x2,y2) 的和就是pre[x2][y2] - pre[x1-1][y2] - pre[x2][y1-1] pre[x1-1][y1-1]。这个公式容易记反我的土办法是画个田字格把多减的那块补回来。差分是前缀和的逆运算用来处理“区间加、最后统一查询”的题目。一维差分在左端点加、右端点后一位减最后做一次前缀和还原。二维差分稍微绕一点四个角分别加加减减写的时候对着纸推一遍比硬记靠谱。二分我准备了三个版本按需取用from bisect import bisect_left, bisect_right # 找第一个 x 的位置 i1 bisect_left(a, x) # 找第一个 x 的位置 i2 bisect_right(a, x) # 手写版本方便改成自定义条件 def lower_bound(a, x): lo, hi 0, len(a) while lo hi: mid (lo hi) // 2 if a[mid] x: lo mid 1 else: hi mid return lo库函数的版本更快但只能用于有序数组上的值比较。有些题目要求“第一个满足某条件的位置”条件不是简单的比大小那就得手写。手写的时候关键是循环不变量要想清楚lo左边永远是falsehi右边永远是true这样退出循环时lo hi就是答案。二分答案是我用得最多的技巧。题目问“最小的最大值”或“最大的最小值”十有八九是二分答案加判定函数。判定函数通常贪心就能写整体复杂度 O(n log V)V 是答案范围。这类题目的难点不在二分本身而在判定函数怎么写才不漏解建议写完先跑几组小数据对着暴力验证。3.3 字符串与日期处理模板字符串题在蓝桥杯里出现频率不低尤其是填空题里的回文、子串计数。Python的字符串切片极其方便s[::-1]就是反转判断回文直接s s[::-1]。但要小心切片产生新对象循环里大量切片会拖慢速度这时改成双指针判断更合适。KMP的前缀函数模板我建议备一份虽然用s in t能解决大部分查找问题但涉及“最短循环节”“前后缀匹配长度”时就得靠它def prefix_function(s): n len(s) pi [0] * n for i in range(1, n): j pi[i - 1] while j 0 and s[i] ! s[j]: j pi[j - 1] if s[i] s[j]: j 1 pi[i] j return pi算完之后最小循环节长度是n - pi[n-1]前提是 n 能被这个长度整除否则说明不循环。这个结论在填空题里直接省掉一大段推导。日期类题目几乎每年都有手算容易错用datetime最稳from datetime import date, timedelta d date(2000, 1, 1) end date(2024, 12, 31) cnt 0 while d end: if d.weekday() 0: # 0是周一 cnt 1 d timedelta(days1) print(cnt)weekday()返回 0 到 6分别对应周一到周日isoweekday()返回 1 到 7。这两个容易混我习惯统一用weekday()在纸上标好对应关系。闰年判断直接用calendar.isleap(y)别自己写y % 4 0 and y % 100 ! 0这种容易漏条件。注意datetime支持的范围是公元1年到9999年题目如果涉及超大年份或者需要按自定义规则算日期还是得手写。手写时把月份天数存成列表闰年时改二月这个套路比任何公式都好用。4. 进阶算法模板搜索、图论与动态规划这一层是拉开分数的关键。我的建议是每个大类都练到能默写但不要贪多先把最高频的那几个吃透。4.1 搜索模板DFS、BFS与剪枝DFS的骨架非常固定本质是递归加状态标记def dfs(u, depth): if depth target: # 处理答案 return for v in graph[u]: if not visited[v]: visited[v] True dfs(v, depth 1) visited[v] False这里最容易错的地方是回溯时机。标记要在进入递归前设置取消要在递归返回后立刻执行。如果中途有return记得在返回前取消标记否则状态会污染后续搜索。我踩过这个坑一道排列题死活少几种情况查了半小时才发现是提前返回时漏了回溯。BFS用于求最短步数队列用collections.deque而不是列表因为列表的pop(0)是 O(n) 的数据量一大就成瓶颈from collections import deque def bfs(start, n, m, grid): dist [[-1] * m for _ in range(n)] q deque([start]) dist[start[0]][start[1]] 0 dirs ((1, 0), (-1, 0), (0, 1), (0, -1)) while q: x, y q.popleft() for dx, dy in dirs: nx, ny x dx, y dy if 0 nx n and 0 ny m and dist[nx][ny] -1: dist[nx][ny] dist[x][y] 1 q.append((nx, ny)) return dist方向数组写成元组的元组比列表稍微省一点内存遍历也略快。边界检查写成0 nx n这种链式比较Python里比nx 0 and nx n快一点也别小看这一点BFS里这个判断会执行几百万次。剪枝是搜索题拿分的关键。常见的剪枝手段有三种可行性剪枝、最优性剪枝、搜索顺序优化。可行性剪枝是判断当前状态是否已经不可能满足条件直接返回最优性剪枝是当前代价已经超过已知最优解就停搜索顺序优化是把选择少的节点先搜索减少分支。三种结合用往往能把指数级搜索压到可接受范围。4.2 图论模板并查集、最短路与拓扑排序并查集用得极广从连通块计数到最小生成树都靠它。迭代版避免递归深度问题parent list(range(n 1)) def find(x): while parent[x] ! x: parent[x] parent[parent[x]] x parent[x] return x def union(a, b): ra, rb find(a), find(b) if ra ! rb: parent[ra] rbparent[x] parent[parent[x]]这行是路径压缩把当前节点直接挂到祖父节点上下次查找就快一层。如果要按秩合并再维护一个rank数组把矮树挂到高树上。绝大多数题目只做路径压缩就够了。单源最短路首选Dijkstra加堆import heapq def dijkstra(s, graph, n): INF float(inf) dist [INF] * (n 1) dist[s] 0 pq [(0, s)] while pq: d, u heapq.heappop(pq) if d dist[u]: continue for v, w in graph[u]: nd d w if nd dist[v]: dist[v] nd heapq.heappush(pq, (nd, v)) return distif d dist[u]: continue这行是“懒惰删除”用来跳过堆里的过期条目。没有这行程序结果也对但会慢不少因为同一个节点可能被反复弹出。多源最短路用Floyd三重循环注意把k放最外层写错了结果会很诡异for k in range(n): for i in range(n): for j in range(n): if d[i][k] d[k][j] d[i][j]: d[i][j] d[i][k] d[k][j]内层加个if d[i][k] INF: continue能省不少时间。另外Python的三重循环在 n 到五百时就有点吃力了n 到一千基本必超时这时候要考虑换算法或者用其他技巧。拓扑排序用入度队列from collections import deque def topo_sort(n, adj, indeg): q deque(i for i in range(1, n 1) if indeg[i] 0) order [] while q: u q.popleft() order.append(u) for v in adj[u]: indeg[v] - 1 if indeg[v] 0: q.append(v) return order if len(order) n else []返回空列表表示存在环这个判断在题目里经常用到比如检测依赖关系是否矛盾。4.3 动态规划模板背包、线性与区间背包是DP里出现频率最高的题型。01背包一维滚动的写法必须背下来dp [0] * (V 1) for w, val in items: for j in range(V, w - 1, -1): if dp[j - w] val dp[j]: dp[j] dp[j - w] val内层逆序是关键保证每件物品只用一次。如果写成正序就变成了完全背包也就是每件物品可以用无限次。这个区别我在初期老是记混后来用一句口诀记逆序是01正序是完全。多重背包如果每件物品数量少直接拆成多个01背包即可。数量大时用二进制拆分把 k 件物品拆成 1、2、4、8…… 这样的组合能把复杂度从 O(V·Σk) 降到 O(V·Σlog k)new_items [] for w, val, cnt in items: k 1 while cnt 0: take min(k, cnt) new_items.append((w * take, val * take)) cnt - take k 1这段代码很短但理解起来需要想一下任何数量都能表示成若干个2的幂次之和所以拆完之后每种组合都能凑出来。线性DP里我常备的是最长递增子序列贪心加二分的写法是 O(n log n)from bisect import bisect_left def lis(a): tails [] for x in a: i bisect_left(tails, x) if i len(tails): tails.append(x) else: tails[i] x return len(tails)注意tails数组本身不是某个具体的子序列它只是各个长度对应的最小结尾值别拿它当答案输出。区间DP的骨架是枚举区间长度、起点、分割点三层循环for length in range(2, n 1): for i in range(n - length 1): j i length - 1 for k in range(i, j): dp[i][j] min(dp[i][j], dp[i][k] dp[k 1][j] cost(i, j))cost(i, j)是和并代价比如石子合并里就是区间和用前缀和预处理后 O(1) 拿到。这个模板几乎一字不改就能套用属于性价比极高的一个。5. 赛场策略与调试技巧算法之外的功夫往往决定了最终名次。这部分讲的是怎么把已有的水平稳定发挥出来。5.1 暴力打表与对拍拿分的底线不是每道题都能想出正解。遇到卡住的题目先写暴力拿部分分这是个很实际的策略。暴力的写法要尽量简单能给的分一定给满。打表是一个被低估的技巧。如果题目问的是某个固定范围内的结果而且数据规模不大可以直接在本地跑一遍暴力把所有答案算出来然后硬编码到提交的代码里。比如求一百万以内的某种数的个数本地跑几分钟出结果提交时代码里只写一个字典或者列表瞬间通过。用这个技巧要注意两点表不能太大导致代码超长以及确认题目没有多组查询且范围超出表。对拍是验证自己思路的利器。写一个暴力版本和一个优化版本用随机数据生成器造大量小数据两个程序分别跑比较输出。如果几百组数据都一致基本可以放心提交。我准备的一个简易对拍脚本长这样import random, subprocess for t in range(300): n random.randint(1, 12) with open(in.txt, w) as f: f.write(str(n) \n) f.write( .join(str(random.randint(1, 20)) for _ in range(n))) r1 subprocess.run([python, brute.py], stdinopen(in.txt), capture_outputTrue, textTrue).stdout.strip() r2 subprocess.run([python, fast.py], stdinopen(in.txt), capture_outputTrue, textTrue).stdout.strip() if r1 ! r2: print(差异出现输入, open(in.txt).read()) print(暴力, r1, 优化, r2) break跑三百组小数据通常一分钟内能出结果比手工造数据高效太多。5.2 大数、精度与边界处理Python的整数是任意精度的题目里出现大数运算时不要习惯性地取模。但大整数的运算速度会随着位数增长而下降一百位以内的数字运算还很快几千位就会明显变慢。如果题目只需要最后几位那就一边算一边取模。浮点数方面比较两个浮点数不要用改用差值绝对值小于一个很小的数比如1e-9。输出保留小数位用格式化字符串print(f{ans:.2f})它会自动四舍五入比自己写round更符合评测预期。注意round(2.675, 2)的结果可能是 2.67 而不是 2.68因为二进制表示不精确涉及金额类题目要格外小心。边界处理是失分重灾区。空输入、只有一个元素、全部元素相同、最大最小值、负数下标这几个场景我都会在心里过一遍。尤其是数组长度为1时的循环range(1, n)直接不执行有时候这是对的有时候会导致答案错误取决于题目是否要求输出单个元素本身。提示除法要分清//和int(a / b)。前者是向下取整后者是先转浮点再截断在负数上结果不同。比如-7 // 2是 -4int(-7 / 2)是 -3。涉及负数取整的题目这个差异会直接导致答案错误。5.3 时间分配与提交顺序我习惯的时间分配是这样的前十分钟通读全部题目标出哪些是明显会做的哪些需要想一想哪些完全没思路。然后按“会做且写得快”的顺序开做每道题控制在十五到二十分钟内。做完一道立刻提交不要攒着最后一起交万一最后一分钟网络卡了损失无法挽回。填空题排在前面做因为不需要考虑时间复杂度和边界能算出来就行。编程题先做数据范围小的因为范围小意味着暴力可能能过拿分快。压轴题留到最后如果只剩半小时还没思路果断写暴力加特判把能拿的部分分拿到手。还有一个细节代码提交前把调试用的print全部删掉或者注释掉。输出多余内容在大多数评测系统上会判定为格式错误白丢一道题的分。我见过有人因为留了一行调试输出从满分变成零分这个教训值得记住。6. 常见问题与排查速查表把踩过的坑整理成表赛前扫一遍能省下大量现场排查时间。下面这些几乎都是我自己或者身边的人真实遇到过的。6.1 运行时错误与答案错误排查现象常见原因排查动作RecursionError递归层数超过默认限制调大 setrecursionlimit或改迭代写法Runtime Error除零、下标越界、类型不匹配检查分母是否可能为0下标范围输入是否为空Time Limit复杂度过高或IO太慢换 bulk 读取检查循环是否可降维Memory Limit开了超大二维数组用一维滚动数组或 bytearrayWrong Answer边界条件、取整方向、未清空全局状态手动跑小数据检查多组数据间变量是否复位输入读不完用了 input() 遇到空行中断改用 sys.stdin 逐行或整体读取输出格式错行尾空格、多余换行、缺少分隔符对照题目输出样例逐字符比对多组数据不清空全局变量这个问题特别隐蔽。比如并查集的parent数组、DP的状态数组如果写在函数外层上一组数据的残留会影响下一组。我的习惯是把所有状态定义在solve()函数内部每次调用都是全新的这样最省心。另外列表推导式里的变量作用域也容易出问题。Python 3 里推导式有独立作用域外层同名变量不会泄漏这个和 Python 2 不同如果看的是老教程要注意。6.2 赛前模板自检清单比赛前一天我会按这份清单把自己的模板库过一遍确认每个模块都能独立跑通环境层sys.setrecursionlimit、sys.stdin.buffer.read()、sys.stdout.write三件套是否到位版本号是否和评测机对齐。数学层gcd、lcm、快速幂、线性筛、组合数五个模板各跑一组样例。序列层一维和二维前缀和、一维和二维差分、三个二分版本、离散化。搜索层DFS回溯、BFS最短路、方向数组确认回溯位置没写错。图论层并查集迭代版、Dijkstra、Floyd、拓扑排序各测一组。DP层01背包、完全背包、多重背包二进制拆分、最长递增子序列、区间DP。工具层itertools.permutations、collections.Counter、deque、heapq、bisect、datetime确认导入名没写错。这份清单看起来长实际过一遍不到一小时。我带过一个学妹她赛前一天照着过了一遍第二天比赛时遇到一道多重背包直接套模板改了两行就过了而旁边的人在手写二进制拆分时写错了下标。这就是准备的价值。最后分享一个我自己用了很久的小技巧把模板按功能拆成多个文件文件名用中文比如快速幂.py、并查集.py比赛时新建文件直接复制内容。文件开头写一行注释说明这个模板的输入输出格式比如“输入两个整数a b输出a^b mod pp需自行修改”。隔一个月再看也能三秒钟想起来怎么用比什么都记在脑子里靠谱。
返回列表