如何写一篇标准的比赛总结

零、写完比赛就完了?不,总结才是真正开始

很多选手打完一场比赛之后,看一眼排名,感慨一下"这道题我本来能过的",然后关掉网页。等到下一场比赛,同样的错误再来一遍。

这不是因为你不够努力,而是因为你没有把比赛的经验"固化"下来。

比赛的三个半小时是高度紧张的——你需要在时间压力下读题、想思路、写代码、调 bug、卡常。这个过程产生的经验和教训非常宝贵,但也非常容易遗忘。如果不及时写总结,两周之后你能记住的东西不会超过两成。

一篇好的比赛总结,能帮你做到三件事:

  1. 把"感觉"翻译成"结论"。比如"这道题好难"不是结论,"这道题的难点在于需要把二维问题转化成一维"才是结论。
  2. 建立自己的错题知识库。每次比赛的失误点,积累下来就是你最个性化的训练资料。
  3. 复盘决策过程。你为什么先开了 A 题而不是 B 题?卡在 C 题的时候为什么没有跳过去?这些策略层面的反思,比单道题的解法更有长期价值。

下面,我们把这四个问题拆解成总结的四个步骤。


一、第一步:整体难度分析

1.1 你要回答什么问题

打开一场比赛(比如一场 Codeforces Round、一场洛谷月赛、一次 NOIP 模拟赛),第一件要做的事不是看每道题的题解,而是先对整场比赛的难度做一个宏观判断。

这一步的目的是建立"参考系"——以后你回头看这篇总结时,能立刻回忆起这场比赛在你当时水平下的定位,知道哪些题是"该拿的",哪些是"该放的"。

1.2 怎么写

按题目顺序,对每道题给出你的难度评估。不要求精确到洛谷的难度评级,可以用你自己的语言描述。关键是要有对比——跟平时训练的题比,跟你打过的其他比赛比。

示范格式:

A 题:签到题,考察基础输入输出和条件判断,相当于洛谷入门/普及-难度。正常 5 分钟内应该通过。

B 题:中等偏下的模拟/构造题,代码量稍大但不涉及复杂算法,相当于普及/提高-难度。预计用时 15~20 分钟。

C 题:图论 + DP 的综合题,需要先建图再跑 DP,细节较多,相当于提高-/提高难度。预计用时 40~60 分钟。

D 题:数学 + 数据结构,需要比较巧妙的转化,难度较高(提高+/省选-)。在时间有限的情况下不建议硬刚。

E 题:防 AK 题,涉及高级算法(后缀自动机 / 网络流),远超当前水平,不考虑。

总体评价:这场比赛的梯度设置合理(A 签到 B 中档 C 综合 D 压轴),相比上周的 XX 比赛,思维难度更高但代码量更小,整体难度在提高组中偏上。

1.3 要点提醒

  • 不要只写"难/简单"。说"A 题简单"没有信息量,说"A 题考察 for 循环 + 取模,5 分钟可过"才有。
  • 标注你预期自己能做出来的题。比如"A B 是保底题,C 是争取题,D 可以看部分分"——这是总结之后做题策略复盘的基础。
  • 对比预期分数与实际得分。先根据自己的难度判断,估算一个"我应该拿多少分"的预期值,再和最终实际得分做对比。差距较大的话,不管是比预期高还是低,都值得分析原因——是题比想的简单、还是某道题超常发挥、还是策略失误丢分了。
  • 如果比赛有官方题解或洛谷上的民间评级,可以附在题号旁边作为参考。但你自己的主观判断更重要——因为主观判断反映了你当前的认知水平,而这个认知水平本身就是需要被修正的对象。

二、第二步:逐题知识点复盘

这是总结的核心部分。对比赛中的每一道题(哪怕是签到题),都要走一遍复盘流程。但解决的题和没解决的题,复盘的重点是不同的。

2.1 场上做出来的题:找闪光点

对于在比赛中顺利通过的题目,最忌讳的就是写一句"轻松 A 掉"然后跳过。能做出来的题一样有总结价值——你要问自己:为什么我能做出来?有没有更好的做法?

你需要重点关注两个方面:

第一:巧思性 / 思维闪光点。这道题有没有一个关键的转化、一个巧妙的观察,让你"豁然开朗"?这个闪光点如果下次遇到类似的题目,能不能复用?

正面示例:"C 题的关键在于发现"操作是可逆的",于是每个状态连通块可以用并查集维护。这个思路和之前做的'关押罪犯'很像——都是把看似复杂的操作转化为连通性问题。以后遇到'可逆操作'类的题目,第一反应应该考虑并查集。"

反面示例:"C 题用了并查集。"(没有说为什么,没有建立联系。)

第二:代码构建上的特点。这道题的代码有没有值得一提的写法?比如用了 STL 的某个不常用的容器?用了某种边界处理的技巧?递归改非递归?

正面示例:"B 题需要维护一个支持插入和查询中位数的集合。我用的是两个堆(对顶堆)的技巧,代码很短,而且 O(log⁡N)O(\log N) 操作。注意插入时要先插到左侧的大根堆,再把堆顶弹出插到右侧的小根堆——顺序写反会导致中位数偏移一位。"

反面示例:"B 题用 set 过了。"(没有说明为什么用 set,有没有更优的方案。)

2.2 场上没做出来的题:分析原因

对于没做出来的题,老老实实回答四个问题:

(1) 我被什么卡住了?

是读题读错了?思路方向完全错了?想到了正确方向但某个细节没推出来?还是代码写对了但被数据范围坑了?

把"卡住"的那个具体时刻描述出来。比如:

"看到数据范围 N≤105N \le 10^5 和最多 QQ 次查询,我第一反应是线段树。写了 30 分钟发现需要维护的是区间中的第二大值,线段树上合并两个子区间的逻辑非常复杂,写不出来。"

(2) 正解是什么?我差在哪一步?

用一两句话说清楚正解的核心思路,然后标出你和正解之间差的那一步。

"正解是用 ST 表,因为第二大值具备可重叠性(重叠部分不算重),所以可以用两个长度 2k2^k 的区间合并求值,O(1)O(1) 查询。我差的一步是:没有意识到"第二大值"这个运算也满足可重叠性——我默认以为只有 max/min 可以,没去想第二大值本质上就是'取前两个最大的',也满足重叠性质。"

(3) 为什么没想到?

这里要做深一点的反思:

  • 是知识盲区(完全不知道这个算法/技巧)?
  • 是熟练度不够(知道这个算法但没想到用它)?
  • 是思维定势(被自己的第一个思路锁死了,没跳出来)?
  • 是心态问题(时间紧迫导致慌张,静不下心来分析)?

如实记录,不要不好意思。这些记录以后会变成你最有效的"错题本"。

(4) 下次遇到类似的题,我会怎么思考?

给未来的自己写一条"行动指令"——不是笼统的"下次注意",而是一个具体的、可执行的思维步骤。

"下次遇到'多次查询 + 静态数组 + 某种区间运算'的组合,按这个顺序思考:① 运算是否可重叠?(是 → ST 表,O(1)O(1);否 → 线段树/树状数组)② 数据范围是否允许 O(log⁡N)O(\log N)?(是 → 线段树;否 → 必须 O(1)O(1))"


三、第三步:为每道题写一份"未来能看懂"的题解

这是比赛总结中非常重要的一步。 难度分析和逐题复盘帮你理解了"发生了什么",但题解是把这些理解"固化"下来的关键。一份好的题解能让你一个月后不依赖任何外部资料,仅凭自己的记录就能完全回忆起这道题的思路和细节。这一步写扎实了,整篇总结的长期价值就稳了。

3.1 写给谁看

这份题解的读者不是别人,是一个月后回来看的自己。

一个月后的你,已经忘记了这道题的细节,但还记得基本的知识背景。所以你不需要从零开始交代所有前置知识,但需要交代这道题特有的关键信息——那些你如果不说、一个月后肯定想不起来的东西。

3.2 一份"可回溯题解"的推荐结构

对于每道题,建议按以下 5 个部分来写:

部分 内容 作用
题意简述 用 2~3 句话把问题说清楚,去掉原题面的故事包装 快速回忆题目在问什么
数据范围 N≤?N \le ?,M≤?M \le ?,时限和空间限制 判断"我的解法为什么可行/不可行"的前提
关键转化 / 观察 这道题最核心的那一步(可能是一个等式变形、一个图论建模、一个数据结构选择) 最重要的部分——这就是你当时卡住的地方或灵光一闪的地方
算法流程 分步骤描述解法,每一步后面跟上复杂度 确保你能把思路转成代码
核心代码片段 只贴最关键的几行,不要贴整个程序 一个月后看到这几行就能回忆起完整的写法

3.3 示范

以一道经典的 Codeforces 题"给定数组,问最长的子数组使得最大值与最小值之差不超过 kk"为例:

题意简述:给定长度 NN 的数组 aa 和整数 kk,求最长的连续子数组,满足子数组的 max⁡−min⁡≤k\max - \min \le k。

数据范围:N≤105N \le 10^5,a_i≤109a\_i \le 10^9。

关键转化:子数组的 max⁡\max 和 min⁡\min 可以由两个单调队列在 O(N)O(N) 内维护。右端点 rr 向右移动时,维护当前窗口 [l,r][l, r] 的最大值和最小值,如果 max⁡−min⁡>k\max - \min > k 就移动左端点 ll 直到满足条件。

算法流程:

  1. 用 deque 维护当前窗口的最大值(递减单调队列)和最小值(递增单调队列)。
  2. rr 从 11 遍历到 NN:将 a_ra\_r 加入两个单调队列;如果队首最大值 − 队首最小值 > kk,移动 ll 并弹出不在窗口内的队首元素;更新答案 max⁡(ans,r−l+1)\max(ans, r - l + 1)。
  3. 复杂度 O(N)O(N),每个元素进出单调队列各一次。

核心代码片段:

while (!max_que.empty() && a[max_que.back()] <= a[r])
    max_que.pop_back();
max_que.push_back(r);
while (!min_que.empty() && a[min_que.back()] >= a[r])
    min_que.pop_back();
min_que.push_back(r);
while (a[max_que.front()] - a[min_que.front()] > k) {
    l++;
    if (max_que.front() < l) max_que.pop_front();
    if (min_que.front() < l) min_que.pop_front();
}
ans = max(ans, r - l + 1);

3.4 要点提醒

  • 只贴关键代码,不要贴整个程序。整个程序你重新写一遍都能写,但关键的几行(比如状态转移方程、边界处理、一个巧妙的 trick)如果不记录下来,下次还是要重新想。
  • 题解不要抄官方题解。官方的语言往往是"从结果倒推"的,看起来每一步都有道理,但不会告诉你"为什么要这么做"。你的题解要写的是"我是怎么想到的"或者"我当初没想到,但别人告诉了我之后我觉得可以这样记住"。
  • 如果一道题你有多种解法,都可以简要记下来。比如"解法一:单调队列,O(N)O(N);解法二:二分答案 + ST 表,O(Nlog⁡N)O(N \log N)"。对比不同解法的优劣,能加深你对各种工具适用场景的理解。

四、第四步:比赛故事与个人感悟

4.1 为什么需要这一步

前三步是"冷"的——难度分析、知识点复盘、题解撰写,都是客观的技术性工作。

但比赛从来不只是技术。你在赛场上经历的紧张、犹豫、懊恼、惊喜,同样是这场比赛的一部分,而且往往是影响成绩的关键变量。把这些情绪和决策过程记录下来,有两层意义:

  • 对自己:看清自己在压力下的行为模式——你是容易死磕一道题还是频繁跳题?你是越挫越勇还是越卡越慌?这些模式不会自然改变,需要先被看见,才能被调整。
  • 对后来:以后翻回来读,你能看到自己的成长轨迹。从"第一次打 CF,A 题都读不懂"到"Div.2 ABCD 全通",这种对比本身就是最好的激励。

4.2 怎么写

不要写流水账("9:00 开始读题,9:05 开始写 A,9:12 交了一发 WA……"),这种记录没有信息量。用关键时间节点 + 当时的心理状态 + 之后的反思的结构来写。

示范:

比赛故事与反思

这场是今年 NOIP 之前的最后一场模拟赛,心态上其实是比较紧张的。

开场 0:00 – 0:20(心态平稳期):A 题签到,B 题模拟,都在计划时间内过了。这时候感觉还不错,觉得今天可能能打出好成绩。

0:20 – 1:00(思路偏离期):C 题读完第一反应是 DP,写了一个 O(N2)O(N^2) 的做法交上去 TLE 了 3 个点。这时候我犯了第一个错误——没有停下来重新分析复杂度,而是开始加各种剪枝优化。事实证明这道题根本不是 DP,而是贪心。反思:当一个做法需要大量"修补"的时候,往往意味着方向本身就错了。下次遇到优化了 10 分钟还没效果的题目,应该立刻回头重新读题。

1:00 – 2:30(死磕期):C 题换了贪心思路,交上去 WA 了 4 个点。这时候心态开始慌了,但又觉得"已经花了一个小时,不做出 C 不甘心",于是没有去看 D。反思:这是我本场最大的策略失误。赛前定下的规矩是"一道题超过 1 小时就跳",但在紧张状态下没能执行。D 题其实是一道裸的二分+最短路,我完全有能力做出来。

2:30 – 3:30(补救期):终于跳去看 D,但只剩一个小时,读题 + 写代码 + 调试,时间完全不够,最后只写了部分分。E 题没看。

整体感受:这场比赛给我最大的教训不是技术层面的,而是比赛策略的执行力。知道该跳题但做不到,比不知道要跳题更让人懊恼。下一场比赛,我打算在桌上放一张便签,写着"60 分钟没 AC 就跳",用物理提示来强化这个习惯。

4.3 可以写的内容

以下角度可以自由组合,不需要每场都全写:

角度 参考问题
心态曲线 整个比赛过程中,哪个阶段心态最好?最差?转折点是什么?
策略复盘 开题顺序是否合理?读题花了多久?有没有看错题?
时间分配 自己估计的用时 vs 实际用时,差距最大的是哪题?为什么?
技术短板 这场比赛暴露了哪些知识漏洞?按紧迫程度排个序
对比反思 和上次比赛相比,有什么进步?有什么退步?
环境因素 是线上还是线下?有没有受到干扰?IDE / 编译环境是否顺手?

五、补充建议

5.1 总结的节奏

  • 刚打完比赛(当天或第二天):趁记忆犹新,先把第二步(逐题复盘)和第四步(比赛故事)的草稿写下来。尤其是那道你卡了很久的题,拖三天之后你就记不清自己"当时想了什么但没想通"了。
  • 一周之内:把第三步(题解)补完。这时候你可能已经看了题解、和别人讨论了、或者自己想通了,写出来的东西更全面。
  • 不需要每场比赛都写长篇总结。日常的训练赛可以只写精简版(每题一句话 + 一句话感想),但重要的比赛(模拟赛、月赛、正式比赛)建议按本文的四步法完整写完。

5.2 常见偷懒陷阱与对策

偷懒做法 为什么不行 替代方案
只贴题解链接,不自己写 别人的题解是别人的思维路径,你看懂了不代表你会想到 看完题解后,用自己的话重新组织一遍
只分析没做出来的题 做出来的题也可能有更优解,也可能只是运气好(数据水) 至少对非签到的通过题,花两分钟确认一下解法是否最优
反思写得太笼统("下次注意时间分配") 没有可操作性的反思 = 没有反思 写成具体的行动指令,比如"CF Div.2 的 C 题超过 40 分钟就跳"
比赛故事跳过不写 策略问题和心态问题是制约成绩上升的核心瓶颈 哪怕只写 5 行——关键决策的时间点和当时的选择——都有价值

5.3 一份总结大概多长?

这个问题经常被问到。答案取决于比赛的类型和你在比赛中投入的深度:

  • 日常训练赛:300~500 字。每题 2~3 句话交代正解思路 + 一句话反思。
  • 阶段性模拟赛:1000~2000 字。四步法都覆盖到,每道值得关注的题有 5~10 行的题解。
  • 正式比赛(NOIP / 省选 / 重要线上赛):2000~4000 字。尤其是比赛故事部分,越详细越好——这类比赛的策略复盘价值远超平时。

不要太纠结字数。核心标准只有一个:一个月后回来看,能不能完全回忆起这场比赛的收获。


六、一个完整的总结模板

下面是一个可以直接套用的模板,[ ] 标记的部分按实际情况填写。

[比赛名称] 总结

一、整体难度分析

题号 难度判断 预期通过 实际通过 简评
A [难度] [√/×] [一句话]
B
C
D
...

总体评价:[2~3 句话,谈梯度设置、思维 vs 代码量、与以往比赛的对比]

二、逐题复盘

A 题:[题目名]

  • 状态:已通过 / 未通过
  • 知识点:[算法/技巧]
  • [闪光点 / 难点](二选一):
    • (已通过)闪光点:[关键的转化、巧思或代码技巧]
    • (未通过)难点:[卡在什么地方] → 原因:[为什么没想到] → 日后思路:[下次怎么做]

B 题:[题目名]

(同上格式)

...

三、题解附录

A 题:[题目名]

题意:[2~3 句] 数据范围:[关键数据] 关键观察:[最核心的一步] 算法流程:[分步描述] 核心代码:

// 只贴关键片段

B 题:[题目名]

(同上格式) ...

四、比赛故事

时间线:[关键节点 + 当时状态]

策略反思:[开题顺序、时间分配、跳题时机]

技术短板:[暴露的知识漏洞,按优先级排序]

整体感受:[2~4 句话总结这场比赛的意义]

---

> **最后想说的话**:比赛总结和算法总结一样,本质上是**你和你自己的对话**。重要的不是格式多规范、文笔多好,而是你有没有诚实地面对自己——承认那道题你就是没想出来,承认那个 bug 就是找了一个小时,承认那场比赛你其实就是心态崩了。
>
> 坦诚的总结,才是有效的总结。

0 条评论

目前还没有评论...