基于题解的训练策略
我们应当认为,中高考与算法竞赛不是智力游戏,它们同时还考察着训练策略、心态调节等能力。
本文参考资料:一个金牌选手的信竞攻略_哔哩哔哩_bilibili,How to practice Competitive Programming [Um_nik version] - Codeforces,liangdl 的学习经历。
糟糕的训练策略
在介绍 “基于题解的训练策略” 之前,让我们先看一下糟糕的训练策略是什么:
首先,L 从不知道哪个地方拿来一道题目。假设是一道数学几何难题好了。
然后,绞劲脑汁想了一个小时,凭感觉这试一下那试一下,辅助线画下来擦了又擦,题目都擦糊了,还是没有想出解法。
最后,无奈之下选择请教帮哥。看到帮哥设了五个未知数,过程写得和英语作文一样,L 从头读到尾,勉强理解,过程一抄就过掉了这道题。
L 疲惫地靠在椅背上,想着在这流逝的一个半小时里,自己竭尽全力还是无法战胜一道数学压轴题。L 感到无比的挫败与沮丧,又想到自己好像什么也没学到,不自觉地陷入自我怀疑。于是,L 开摆了。
以上内容是 liangdl 的真实经历(艺术加工版)。
我们来分析一下这样训练的问题:
没有选择好的训练资源。随机选取的题目要么简单、要么奇怪、要么困难,找到一道好题的概率很小,不要把自己宝贵的精力浪费在这种题上面。
思考没有目的性,没有设定好思考时限。这个方面的内容涉及到解题思维,我在文章最后附了我的 OI & 数学题的解题思维,大伙可以参照一下。
没有选择合适的题解。若一道初中数学几何题需要设 2 个以上的未知数时,这篇题解可以断定没有学习价值,我敢说一定存在更优雅的简单解法。
预期与心态的问题。应该带着“我大概会解不出来的”的预期去写题,否则挫败感几乎是无法避免的,不应该让自己陷进去。
基于题解的训练策略
于是,基于存在的这些问题,liangdl 优化出了一套新的训练策略——基于题解的训练策略!
你想,一道题目,如果你能写出来,那么它在你写之前就已经在你的能力范围之内了(当然不否认简单题目对于思维的强化作用)。只有你需要看题解的题目,才能让你的能力有所提升。
当面对一个新学科的时候,如果没有题解帮助你实现从 0到1 的跨越/积累,刷再多的题也没用。
具体怎么操作呢?
Part 1:筛选题目
拿到一道题目,要判断它值不值得训练,首先看它的来源。好的来源有:老师推荐、历年真题与广受好评的教辅。 这里推荐一个网站:菁优网。可以在这里找到各地区的历年真题。
若没有渠道从这些来源获得题目,或者你觉得好的题源里未必每一道题都值得训练,你就需要看题解了。(这点在语文阅读理解训练里尤其重要,你可以找到好的题目,但是要找到好的答案很难,如果题目的答案不好,那么训练价值也是很少的,可以换一道题目了)
当然,你并不需要把解答从头到尾看得明明白白,那样还有啥训练效果。我的意思是,看看答案大致上是不是条理清晰、简洁就好了。例如,数学题设 5 个未知数、阅读理解的答案写的极其随性简短,没有明确评分标准、OI 题解里全都是“感性理解”“显然”“易得”,这样的题解就可以避雷了。
Part 2:思考题目
首先知道一个事实:你能解出来的题目难度并不等价于你的能力。成功解题是有概率的,这个概率根据你的能力水平会浮动。所以,不要抱着“这题写不出来我就是菜”的心态来写题,而是要抱着“如果我写出来了,我巩固了我的思维;如果我没写出来,我扩展了我的能力”。总之,我只要写题就是赢!
其次,限时。一道题目(当然要看你刷的是什么题,我这里以数学压轴和 OI 题为例),如果你是试了20-30分钟才试出来的,那么其实你还是没有掌握。我个人倾向于认真思考5-10分钟未果就去看题解,不然会带来很大的挫败感。
Part 3:看题解 & 总结复盘
选择一篇好的题解,然后理解它。理解的标准是:能够用简洁的一句话表达出题目的核心。
然后把自己的卡点记录下来,将题解是如何面对卡点的方法,归纳进你的解题思维里。
以上就是“基于题解的训练策略”的全部基础版内容了,掌握这个训练策略并加以坚持,我相信你可以拉爆很多人了(不要拉爆我啊)。最后扩展一点,这个训练策略的三个部分是可以 “多线并行” 的,这就带给了我们极大的自由度,在 OI 这种动辄几个小时的训练中有极大的便利。具体来说,你可以在状态不好的时候筛选题目,状态极佳的时候思考题目 or 看题解,这样就保证了自己不会浪费时间,最大化利用了时间。
附录
OI 的解题思维
理解
- 形式化题面。
- 标出数据范围。
思考
- 先判断能否对应问题类型,再标出奇怪的地方,再使用思考技巧。
- 先广搜,得到几个大致的思考方向,写下来。用数据范围排除掉一些算法。
- 然后选一个深搜。如果想了 10 分钟还是没有进展,就换一个方向。如果所有方向都没有进展,看题解。
- 形式化思考结果
常见 问题类型 的思考方向
- 操作题:思考操作顺序、操作影响、操作影响如何映射到其他东西上等。
- 二维网格:枚举上下边界、按行 DP、格点 DP。
- 博弈题:先找出 必胜 or 必败 的状态。(找全)
然后证明,如果状态不属于 必胜 or 必败 态(反向刻画),就必然属于相反的状态。 - 计数题:考虑不同主体、唯一代表元的贡献。
- 最优化:二分答案、DP、贪心
- 区间计数/最优区间:枚举端点,另一端考虑双指针、二分
- 构造题:考虑无解
一些常见的 思考技巧(适用范围广,强度适中)
- 正难则反
- 考虑单个元素贡献,考虑哪些元素无贡献。无贡献的元素要立刻剥离:2025 CSPST2、最短路公共路径
- 分类讨论(分治)
- 从简化的问题入手
- 关注不变量
- 排序
- 研究操作 前提/影响
- 猜证结论
- 能离线的要离线
- 放入二维平面
- 跳出动态过程(什么样的状态下),研究静态结构(存在什么):双栈序列
一些常见 trick(适用范围小,但强)
图论
- 虚点,超级源点,超级汇点
- 有向图考虑 DAG 解法,缩点。
- 偏序关系考虑差分约束
- 点的状态很少考虑分层图
- 染色:找出主体的不同状态,用边表示状态的异同。
- 连通性:并查集、搜索树。
贪心
- 临项交换
DP
- 状态设计成 恰好 形式的
- 状态设计一定不要有冗余
- 决策集合具有单调增减性,可以优化。
- 数位DP,用mask表示0~9中哪些数出现过
- 不知道从何下手时,先大胆设出来再优化
- 考虑转移时,从新增的元素上下手。
- 小区间变到大区间——>区间DP。
线段树
维护区间信息时考虑线段树。
- 考虑节点与节点、节点与标签、标签与标签之间的合并。
- 考虑节点与节点的合并时,分类讨论至少两种情况,答案落在左/右区间,答案跨越左右区间。
- 遇到难维护的操作,直接暴力再考虑优化/剪枝。区间每个数取模/开方,最多进行 log 次。
代码
- 写出算法流程
- 列出关键变量、数组、函数的定义
- 注意边界条件,dp 考虑边界
调试
- 检查需不需要开 long long
- 有没有 模0 或 除0
- pop 之前有没有判空
- 数组下标有没有 越界/负数,大小有没有开对
- 逐一检查每一个变量,数组,是否正确维护。
- 初始值
- 中间值
- 边界值
复盘
- 记录卡住的地方(思考、代码或调试)
- 补充笔记,记录学到了什么,下次要避免什么。
数学的解题思维
解题步骤
- 标数据,识别题目类型。
- 根据几何关系,列出思考方向。
- 根据常见套路,列出思考方向。
- 关注一些宏观的东西
- 关注对称性
- 将图形转化为已知模型的图形
- 先把可能用上的思考方向列出来,越多越好,再选择一个思考方向深度思考,思考 5 分钟没有进展,就换一个思考方向。
题目类型带来的思考方向
- 求线段长:勾股、和差、旋转、等面积
- 求比例:分别求两条线段长、找相似
- 求角度:内角和、等腰对等角、八字
- 求面积:公式、铅锤高、割补、平行线转换、等分点转换、容斥
- 求最小值:将军饮马、垂线段、找轨迹、全等转化线段、费马点、平移定点、旋转
- 求最大值:三角形三边关系(注意这个三角形不能有定角或者定三边,因为这样无法三点共线)、垂线段、找轨迹、旋转
(最值问题本质上是在把题目转化为一定一动)
几何关系带来的思考方向
- 中线:八字全等(倍长)、中位线、平分面积
- 角平分线:对称性、做垂直、角平分线定理
- 垂线:等面积、勾股
- 等腰:三线合一、腰上小高之和等于高
- 特殊角:延长、垂直、构等腰、拆分
- 直角三角形:斜边中线
- 翻折:对称性、勾股、中垂线、悬空直角、等腰、角平分线、连接对应点、翻折中点出直角
常见套路带来的思考方向
- 平行三剑客:翻折平行出等腰
- 旋转:有特殊三角形时
- 一线三:多个等角、特殊三角形、悬空直角
- 手拉手:特殊三角形
- 十字架:矩形 / 正方形
- 半角模型:旋转
- 射影定理导角
- 构造中位线:四边形上有双中点,取对角线中点构造中位线
- 一边一角构全等
- 两倍角三角形:内外构等腰
- 截长补短:两线段和等于另一线段
- 两倍角、九十度:绝配角构等腰
一些意识
- 存在大量的 等量 or 比例,大胆设未知数列方程。