
1. 路线整体设计先把“算法竞赛”这件事想清楚先说个很多人问过我的问题算法竞赛到底在考什么很多人以为考的是“会不会背模板”“知不知道某个冷门算法”入坑之后才发现完全不是这么回事。从我的实际参赛和带新人的经验来看算法竞赛核心考的是三件事把问题抽象成数学模型的能力、在有限时间内设计正确算法的能力、把算法用代码精准实现的能力。这三件事缺一不可而且每一件都不是靠突击能补上来的。所以这份路线图的第一个设计原则是不按“算法名”排列按“能力成长阶段”排列。网上很多学习路线是罗列式的什么“二分、贪心、DP、图论、数论”挨个排一遍看起来全面实际上没用——因为新手根本不知道自己该从哪儿下手也不知道学到什么程度算“会了”。我这份路线会明确告诉你每个阶段你要掌握什么、用什么题检验自己、遇到瓶颈怎么突破。第二个设计原则是以赛代练以题带学。现在很多自学者容易陷入“看视频→抄代码→觉得自己会了”的虚假充实感。我见过太多人把某个算法的原理讲得头头是道结果一上OJOnline Judge在线评测系统连最简单的变式都写不对。原因很简单看懂和会写之间隔着几百道题的距离。所以这份路线里每个知识点我都配了“必须刷到的题型”和“检验标准”确保你学完一个模块之后真的能在限时环境里写出来。第三个设计原则是语言选型要务实。算法竞赛圈的主流语言是C这不是情怀是实打实的效率问题。C在竞赛里有几个无可替代的优势STL标准模板库提供了现成的数据结构和算法模板写起来比其他语言快运行速度快同样的复杂度在Java和Python可能TLETime Limit Exceeded超时C能过几乎所有OJ和比赛都支持C生态最完整。如果你目前只会Python也不是不能参赛但到了中后期你会发现很多优化技巧在Python里没法落地到时候再转语言成本更高。我的建议是无论你最终用不用C至少前三个月把它当主力语言练。还有一点要提前说清楚算法竞赛和做工程开发是两码事。工程看重代码可读性、可维护性、模块化设计竞赛看重的是“在最短时间内写出能跑对的代码”。这就意味着很多工程上的好习惯在竞赛里反而要刻意调整比如不用写详细的注释、不用做防御性编程、变量名可以短一点这些都是为了提高编码速度。当然这不代表竞赛代码可以乱写而是在“够用就好”和“能快速调试”之间找平衡。2. 第一阶段语言基础与数据结构地基约1~2个月2.1 C语法到底学到什么程度才够用很多新人问过我一个特别实在的问题“C语法那么多我是不是要把《C Primer》啃完才能开始刷题”我的回答是绝对不用而且千万别这么干。竞赛需要的C是一个极小子集你甚至不需要了解面向对象、继承、多态、模板元编程这些概念因为这些在竞赛里几乎用不上。你真正需要熟练掌握的是下面这几块输入输出cin/cout以及scanf/printf两种方式都要会特别是格式化输出比如保留几位小数、控制宽度这些。基本数据类型和运算int、long long、double、char、bool以及类型转换、取整技巧、自增自减的坑。分支和循环if/else、for、while、do-while的灵活使用。数组和字符串一维数组、二维数组、字符数组、C风格字符串和string类的常见操作。函数传值、传引用、默认参数、递归函数。指针和引用至少理解“指针指向地址”这个概念后面学链表、树的时候会用到。我说个实际的数据如果你每天保持2~3小时的投入语法部分两周就能过关。检验标准很简单——去洛谷或Codeforces找几道A题最简单的题不看任何资料能独立ACAccepted通过5道以上说明语法这关过了。注意是“独立AC”不是“看了题解之后觉得懂了”。这个区别特别关键很多人就是栽在这里一遇到问题就翻题解刷了100道题感觉啥也没留下。还有个小经验从第一天开始就养成用文件输入输出重定向调试的习惯。具体来说在本地调试时用freopen(in.txt,r,stdin); freopen(out.txt,w,stdout);这种写法把输入输出导向文件方便构造测试数据。正式提交前再把这些注释掉。这个习惯能大幅提升你构造测试样例的效率后面调试复杂题目的时候会感谢这个决定。2.2 必须熟练掌握的STL容器STLStandard Template Library标准模板库是C竞赛选手最趁手的兵器。很多新手会纠结“要不要自己手写数据结构”我的建议是竞赛中能用STL就用STL不要重复造轮子。原因很现实手写数据结构既费时间又容易出bug而STL经过数年优化性能和数据正确性都远超你临场写的版本。当然面试或考研这种场景另说但纯竞赛场景STL优先没有悬念。你需要熟练掌握的STL容器大概有七个我按使用频率排个序vector动态数组竞赛中使用频率之王。要熟练使用push_back、pop_back、size、clear、resize、迭代器遍历还要知道怎么用sort(v.begin(), v.end())排序。string字符串操作支持拼接、substr截取、find查找、compare比较。stack和queue栈和队列注意stack没有迭代器queue也没有只能通过push/pop操作。deque双端队列可以在头部尾部都做插入删除但性能比vector略低。priority_queue优先队列默认大顶堆做贪心和图论算法时是神器。要会自定义比较函数来实现小顶堆。set / multiset集合自动去重排序底层是红黑树插入删除查找都是O(logn)。map / multimap键值对映射同样底层红黑树常用于离散化、计数等场景。除了容器本身配套的算法函数也要会用sort排序、lower_bound/upper_bound二分查找、reverse反转、unique去重、next_permutation全排列。这些函数配合容器使用很多题的代码量能缩减一半。STL学完同样要有检验标准找一个“基于STL实现”的题单比如洛谷的【普及-】难度题库里面涉及排序、映射、优先队列的题要求能做到看到题就能立刻想到用哪个容器而不是去翻笔记。这个熟练度一般需要2~3周的持续练习才能达到。2.3 基础数据结构从数组到树和图的跨越有了C语法和STL做底子接下来就是数据结构的学习。第一阶段要掌握的数据结构并不多但每一个都极其重要它们是后续所有高级算法的承重墙。第一个是链表。虽然STL里有list但竞赛中直接手写链表的机会不多更多时候是用数组模拟链表——也就是静态链表用两个数组分别存“值”和“下一个节点的下标”。为什么要学这个因为有些内存紧张、卡常数的题目用动态链表的new/delete会超时数组模拟更快更稳。第二个是栈和队列。这两个概念本身不难难的是应用场景识别。比如括号匹配用栈、单调栈求“下一个更大元素”、BFS广度优先搜索用队列、滑动窗口最大值用单调队列——这些题目形态完全不一样但底层都是栈和队列的变形第一阶段至少要把这些经典应用刷一遍。第三个是二叉树。先掌握基础的遍历方式前序、中序、后序、层序然后学二叉搜索树的插入、删除、查找操作。这里有个常见的坑很多新手学二叉树只看“插入”“查找”就觉得自己会了实际上竞赛里考得更多的是“根据遍历序列重建二叉树”这种综合题一定得多练。第四个是图。第一阶段不需要深究图的算法但要彻底理解图的两种存储方式邻接矩阵和邻接表。邻接矩阵用二维数组存适合稠密图邻接表用vector数组或链式前向星存适合稀疏图也是竞赛中用的最多的。很多新生一上来就纠结“到底用哪种”我的建议很简单不会判断就用邻接表90%的题邻接表都能搞定而且空间上更稳。3. 第二阶段经典算法模块逐个击破约3~4个月3.1 排序、二分、贪心三大基础算法思想排序算法是算法竞赛的开胃菜但很多人只是“会用sort”完全不清楚排序背后的原理这在后面学归并排序求逆序对、学快速排序找第K大时会吃亏。第二阶段开始时我建议你把选择排序、插入排序、冒泡排序、归并排序、快速排序、堆排序都手写一遍重点理解“分治”和“比较排序下界”这两个概念。为什么理解这些这么重要因为排序不只是把数据排整齐它更是一种让无序问题变有序的预处理手段。比如很多题目只要先排个序后面的贪心策略就顺理成章了。再比如归并排序的过程中能顺便统计逆序对这是个典型的“排序算法额外逻辑”的组合题型后面你会经常遇到类似的“在基础算法里塞额外计算”的考法。二分算法是竞赛里最容易“看似会了做就出错”的模块。二分的核心不是“在有序数组里找数”而是“在满足单调性的判定问题上找边界”。什么意思就是说不管数据长什么样只要你能构造出一个“某一点之前全满足条件、之后全不满足”的判定函数problem就能用二分找到这个分界点。这就是二分答案法的精髓。初学者最常见的坑有两个一个是边界写错导致死循环或漏答案另一个是不知道什么时候该用二分。关于边界我分享一个经验统一用l (r - l) / 2来取中点防止lr溢出统一用“闭区间”[l, r]来维护答案并保证每次循环后答案仍在区间内。这样写虽然偶尔会比别人多几次循环但不容易写错竞赛里正确率比常数优化重要得多。关于什么时候二分记住一句话正着做很难但能判断“某个答案是否可行”时就考虑二分答案枚举这个答案。贪心算法是看起来最简单、实际上最需要数学直觉的模块。贪心的本质是“每一步都选当下最优最终得到全局最优”但它并不是什么时候都成立。所以学贪心有一个核心能力要刻意练怎么证明一个贪心策略是对的。你可以用三种方法反证法、归纳法、交换论证法。第一阶段不需要证明得很严谨但至少要有意识地问自己“为什么这个局部最优能推出全局最优”如果答不上来大概率是策略有问题。3.2 深度优先搜索与回溯暴力出奇迹搜索思想是整个算法竞赛的基石。可以这么说很多看起来高深的算法本质都是“暴力搜索加剪枝”的优化版本。所以第二阶段一定要把DFS深度优先搜索和回溯吃透这是比任何“高级算法”都重要的基本功。DFS的入门是“全排列”和“子集生成”这两个经典问题然后过渡到“迷宫寻路”“连通块计数”这类图上的搜索。学习DFS时有一个认知要尽早建立DFS的本质是递归地枚举所有可能的状态并用“状态”概念统一描述问题。比如全排列的状态是“当前填好的前缀”迷宫的状态是“当前位置”背包问题的状态是“当前考虑的物品和已占用的容量”。一旦你学会用状态来描述问题后续学动态规划就会特别顺畅因为DP的本质就是“聪明的搜索”——把搜索过程中重复计算的子问题记录下来。回溯是DFS的一种特殊形式核心是“尝试→撤销”这一模式典型应用是八皇后、数独、组合求和等。这里有一个很多新手都会犯的错误在递归里修改了全局状态比如标记一个格子被占用了递归返回后忘记撤销。我建议所有使用回溯的地方都要在递归返回后立刻恢复现场。写成代码就是void dfs(int step) { if (step n) { // 到达目标处理答案 return; } for (int i 0; i n; i) { if (!used[i]) { used[i] true; // 标记占用 // 递归进入下一层 dfs(step 1); used[i] false; // 撤销标记恢复现场 } } }这个used[i] true; dfs(...); used[i] false;三部曲你必须形成肌肉记忆因为90%的回溯题错误都出在这一行上。3.3 动态规划从斐波那契到区间DP动态规划DP是整个算法竞赛里最劝退、也最值钱的模块。我可以负责任地说DP学得好不好直接决定你竞赛成绩的上限。图论、数论、字符串这些模块大家差距没那么大但DP题目的区分度极高几乎每场比赛的压轴题都掺杂了DP思想。学DP千万不要上来就背状态转移方程那样等于没学。我建议按下面这个顺序来理解DP第一步认识“最优子结构”和“重叠子问题”这两个概念。用人话说就是大问题的最优解包含小问题的最优解而且不同的大问题会共享同一个小问题。比如斐波那契数列f(5)和f(6)都要用到f(4)这就是重叠子问题。如果你用朴素递归会做大量重复计算如果你用一个数组把中间结果存起来就快得多了。这个过程叫记忆化搜索它是通往DP的天然桥梁。第二步学会“状态表示”。这是DP最难的一步也是最有艺术性的一步。给你一道题你怎么知道dp数组应该开几维、每维代表什么这个没有标准答案但有一个经验可以参考看题目中有哪几个重要的“变动量”这些变动量往往就是状态维度。比如背包问题有“物品编号”和“背包容量”两个变动量所以dp是二维的最长上升子序列有“序列位置”一个变动量所以dp是一维的。第三步学会“状态转移”。有了状态定义转移方程就是回答“当前状态从哪里来”。以最经典的01背包为例dp[i][j]表示“前i个物品、容量为j的最大价值”那么dp[i][j]要么不装第i个物品dp[i-1][j]要么装第i个物品dp[i-1][j-w[i]] v[i]取最大值即可。所有DP的转移方程本质上都在做类似的事情枚举“当前这一步的所有选择”取最优。等01背包、完全背包、多重背包、最长上升子序列、最长公共子序列这些入门题刷完就可以进入区间DP和树形DP了。区间DP的状态通常是“区间[l,r]的某种属性”转移时枚举分割点树形DP的状态通常是“以某个节点为根的子树”转移时在父节点汇总子节点的信息。这两个模块是DP从入门到进阶的分水岭一定要投入足够的时间。3.4 图论基础与最短路算法图论是竞赛中题型最丰富、建模思想最灵活的模块。第二阶段的图论只需要覆盖四条主线图的遍历、拓扑排序、最小生成树、最短路径。图的遍历就是DFS和BFS在图上跑第二阶段要求能做到在10分钟内写出任意图的DFS/BFS遍历代码包括递归版和栈/队列模拟版。其中BFS因为“逐层扩展”的特性天然适合求无权图的最短路径——这也是很多“最短步数”类题目的标准解法。拓扑排序用于处理“有依赖顺序的任务安排”问题核心思想是每次找一个入度为0的节点把它删除并更新相邻节点的入度。如果最后删除的节点数不等于总节点数说明图里有环。这个“环检测”功能在后面的很多算法里都会用到。最小生成树有两个经典算法Prim和Kruskal。新手建议先学Kruskal因为它的思路更简单把所有边按权值排序从小到达依次加入如果加入后不形成环就保留直到所有点连通。判断是否成环用并查集所以这段时间要把并查集也一并学透。并查集是个短小精悍的数据结构代码不到20行但应用极广不只在图论里很多看似无关的题也能用上。最短路算法是图论的重头戏。需要掌握的算法按顺序来Floyd多源O(n^3)适合小数据、Bellman-Ford能处理负权边、SPFABellman-Ford的队列优化虽然复杂度不稳定但大量场合够用、Dijkstra单源只适用于非负权边必须掌握堆优化版。这里有个选择经验大多数题目直接用堆优化Dijkstra复杂度稳定只有在存在负权边时才考虑SPFA数据范围小且要求所有点对最短路时用Floyd。注意近年来不少比赛的出题人会故意卡SPFA所以不要迷信它。4. 第三阶段进阶算法与专题深化约3~4个月4.1 数据结构进阶线段树、树状数组、平衡树到进阶阶段数据结构就从“会用”变成了“会造”。线段树是这里面最重要的一个它能在O(logn)时间内完成区间查询求和、最大值、最小值等和区间修改加一个数、赋一个值等。网上很多教程一上来就甩出建树、单点更新、区间查询、懒惰标记四套模板新人看得头脑发昏。我的经验是先死记模板再理解原理。因为线段树的代码习惯性很强自己临场推容易出边界错误不如先把模板背熟然后在刷题中慢慢理解每个操作的含义。线段树的经典应用场景有这些区间最值和区间求和、区间加/区间乘的懒惰标记、离散化后处理大数据范围、扫描线求矩形面积并。前两个是必学后两个是进阶加分项。树状数组是线段树的轻量级替代品代码更短、常数更小但支持的操作范围有限主要是单点修改前缀和/区间查询。有一个判断经验能用树状数组解决的题尽量别写线段树因为代码短不容易错只有当需要“区间修改区间查询”这种复杂操作时才必须上线段树。平衡树部分竞赛选手一般直接用STL的set/map或__gnu_pbds库真正手写Treap或Splay的机会不多但如果有余力理解它的旋转原理对你理解后续的“可持久化平衡树”这类黑科技会有帮助。如果你目标只是省赛和区域赛拿奖平衡树这块不需要过度深入。4.2 数论与组合数学基础数论是竞赛里的“数学味”最浓的模块也是很多程序员觉得最吃力的地方。但好消息是竞赛数论真正需要你掌握的算法并不多主要是下面这几个欧几里得算法辗转相除法求最大公约数以及扩展欧几里得求不定方程axbygcd(a,b)的一组整数解。质数判定和质因数分解试除法、埃氏筛、线性筛。线性筛不仅要会用还要理解它为什么是O(n)的因为很多题会在此基础上改造。快速幂与模运算计算a^b mod m几乎所有需要“幂运算取模”的地方都在用。逆元除法在模运算下要变成乘以逆元常用费马小定理和扩展欧几里得来求。欧拉函数与欧拉定理用于处理与互质相关的计数问题。组合数学里最核心的是排列与组合的计数公式、二项式定理、容斥原理以及递推关系比如卡特兰数列。这个模块刷题时不做太高要求但求组合数C(n,k)取模的写法一定要练熟——它出现在大量题目里而且用阶乘和逆元预处理的方式实现很固定背下来即可。4.3 字符串算法哈希、KMP、Trie字符串算法在竞赛中占据特殊位置。第一梯队必学的是字符串哈希和KMP。字符串哈希的思想很朴素把一个字符串映射成一个整数方便O(1)比较两个子串是否相等。使用时要注意三个问题进制数选什么常用131、13331、模数选什么常用1e97超过时用unsigned long long自然溢出、如何避免冲突进制和模数选好后冲突率极低但极端数据仍可能卡撞。竞赛中字符串哈希是万金油很多字符串题都能用它混到部分分。KMP算法是处理“模式串匹配”的经典方案核心是next数组也叫前缀函数。很多人学KMP会卡在“为什么匹配失败后跳到next[j]就对了”这里我的建议是暂时不用纠结严格的数学证明先接受它、把它当模板背下来刷几道题之后自然就理解了。KMP的另一个常见变形是“求字符串的最小循环节”这个考频很高。Trie字典树用于维护字符串集合支持插入、查询、前缀统计。它的实现比上面两个简单就是一个多叉树每个节点存一个字符。Trie常与DFS结合做“单词搜索”“最大异或对”这类题后面也常作为AC自动机的前置知识出现。4.4 计算几何入门选学计算几何在竞赛里是个“收益不高但不得不防”的专题省选和区域赛偶尔会出现难度往往集中在代码实现细节上。新手第一遍学可以只掌握向量的基本运算点积、叉积、判断点是否在线段上、判断两线段是否相交、求多边形面积鞋带公式、判断点是否在多边形内。这一块的核心经验是能用整数运算就别用浮点。计算几何的很多公式用整数能做到精确一旦引入double就会面临精度误差处理不当就是WAWrong Answer。如果一定要用浮点记得设一个EPS微小量来控制精度比较。5. 实战训练规划怎么刷题、怎么打比赛5.1 OJ平台怎么选、题单怎么刷再好的学习路线最后都要落到“刷题”这件事上。国内选手最常用的OJ平台有这么几个洛谷题量最大、题单体系最全、中文社区氛围好、Codeforces全球最大竞赛平台每周都有比赛题目质量高、AtCoder日本平台题目梯度设计合理风格偏思维难度、牛客竞赛国内比赛较多、题目类型覆盖全。我的建议是平时以洛谷和Codeforces为双主场。洛谷用来做系统的专题训练因为它有现成的题单比如“【模板】”“【普及-】提高组”等难度分级可以按图索骥Codeforces用来做限时训练和比赛复盘因为它每周都有一到两场正式比赛是检验真实水平的最好考场。刷题节奏上我推荐一个比较可执行的方案平时每天保证2~3道题周末集中做一场虚拟比赛模拟比赛环境的限时做题每周至少整理一次错题和题解笔记。注意这里说的“做一道题”指的是独立思考20分钟以上没有思路才允许看题解看完题解之后不要直接抄代码而是关掉题解自己重新想一遍、写一遍、AC一遍。看题解会的题跟自己写出来的题在考场上是两种完全不同的效果。5.2 如何高效复盘与建立知识体系不会复盘的人刷1000道题也还是原地踏步会复盘的人刷200道题就能有明显的水平提升。复盘不是“把做错的题看一遍正确答案”而是四个步骤第一记录卡点。在题解笔记里写清楚这道题你卡在哪个环节是没想到用二分是状态定义错了还是代码实现细节写错了把这个“卡点”单独记下来每个月回看一次你会很清楚地知道自己的薄弱点在哪。第二总结“套路标签”。每道题AC之后用三五个关键词给它打上标签比如“排序预处理”“二分答案”“树上DFSDP”。过一段时间把所有标签汇总你会意外地发现竞赛题目的套路其实是有限的很多“新题”只是几种旧套路的组合变体。第三多解法对比。简单题可能只有一种解法中档题往往有多个解法比如一道题既能用二分又能用BFS或DP。AC只是起点试着把这道题用其他思路再做一遍或者分析一下不同解法的复杂度差异这对培养“算法嗅觉”特别有帮助。第四周期性回顾。每周抽半天时间不看题解把本周错题重新做一遍。能独立AC说明掌握了还卡壳的题要标记为“复刷题”下一周继续回顾。这种间隔复习的效果远好于一次性刷很多题。5.3 从入门到拿奖的参赛节奏学习路线和参赛计划是强相关的。我不建议“学完再参赛”因为比赛本身是最好的学习催化剂。合理的节奏应该是这样第一阶段结束后大约学完C语法和基础数据结构就可以尝试报名参加洛谷的月赛或者校内的新生赛了。虽然大概率排名靠后但这个过程能让你快速熟悉比赛流程读懂题意、提交代码、查看评测结果、处理罚时规则。第二阶段结束时可以去打牛客的小白月赛和Codeforces的Div.3场次。这个阶段的目标不是拿名次而是稳定通过2~3题。如果能在Div.3场次稳定做出3道题说明你的基础算法掌握得不错已经超过相当一部分人了。第三阶段结束后正式冲击省级赛事是有希望的。省赛的难度通常低于区域赛认真准备、把基础题和中等题稳定拿分拿个省二省三并不难。如果能同时保证DP和图论的正确率冲击省一也有机会。再往上走ICPC/CCPC区域赛拿奖需要第四阶段的积累和固定的团队训练那又是另一个层面的故事了。6. 常见问题与避坑指南6.1 新手最容易踩的五个坑我在带新人的过程中发现有几个问题出现频率特别高这里集中说一遍。第一只看不写。看视频、看题解、看书都能产生“我学会了”的错觉但一到动手就原形毕露。破解方法只有一个强制自己一行代码一行代码地敲哪怕是最简单的题也要自己提交AC。第二眼高手低跳过基础直接学高级算法。我见过不少一上来就学网络流、后缀自动机的同学结果连BFS队列都不熟练。竞赛的知识体系是有严格依赖关系的基础不牢后面全是空中楼阁。第三不会用调试工具。很多人写代码出错就是盯着屏幕肉眼review效率极低。要学会在代码里加断点、打印中间变量或者用gdb等调试工具单步执行。特别是对于一个复杂的状态转移试着把每一层递归的关键变量print出来错误基本一眼就能看出来。第四比赛时死磕一道题。一场比赛2~3小时如果你在某一道题上卡了40分钟以上还在死磕建议先放一放去看其他题目有没有更简单的题可以做。比赛的策略是“总分最大化”不是“某道题非得做出来”。第五忽视读题能力。竞赛题目的题面常常很长夹杂各种背景故事但核心约束条件就那么几句话。要养成“先读输入输出格式、再读数据范围、最后读题面”的习惯数据范围能直接告诉你这道题的期望复杂度——看到n≤10^5基本想的都是O(nlogn)的算法看到n≤20大概率可以直接状压枚举。6.2 内存、时间与精度的常见问题竞赛中报错通常有几种类型编译错误CE、运行错误RE、超时TLE、答案错误WA、内存超限MLE。遇到TLE先看复杂度是否够优再看常数是否过大比如用了cin/cout没有关同步流遇到WA优先怀疑边界条件和数据类型溢出其次才是算法思路错误遇到RE多半是数组越界、栈溢出或者除零了遇到MLE检查是不是开了过大的二维数组或者递归层数太深导致系统栈爆了。这里特别提醒一个细节long long的使用。很多新手习惯全部开int遇到乘法运算结果超过2^31-1就会溢出变成负数。我的经验是只要题目里出现10^9级别的数相乘或加法之后可能超过int范围的一律用long long甚至直接定义成long long是最省心的。与其反复担心溢出不如牺牲一点内存换正确率。精度问题是另一类高频坑。涉及浮点的题尽量不要用float用double判断相等不要写a b要写成fabs(a - b) epseps一般取1e-8或1e-9能转化为整数运算的场景一定优先用整数运算。这不是“洁癖”是在帮你避开无数无意义的WA。6.3 如何突破水平停滞期几乎每个竞赛选手在成长过程中都会遇到一次甚至几次“瓶颈期”症状是连续几场比赛分数没有提升做什么题都觉得自己笨刷题也提不起劲。这个阶段特别正常不要自我怀疑。我的经验是突破瓶颈期通常有三个有效手段第一降维打击。暂时放下难题回到简单中等题重新刷一遍但要求自己用多种解法做同一道题。这个操作看起来“退步”实际上是在补齐你的底层思维漏洞。第二换题源。一直刷同一个OJ容易形成“熟悉感带来的虚假水平”。换个平台刷两周比如从洛谷换到AtCoder你会发现自己原有的熟练度打折但也是在这种不适应中思维才能被真正拉伸。第三找人交流或看他人代码。这一点很管用但常常被忽略。写题解、找队友讨论、观摩高水平选手的代码你会发现同一个问题别人的写法可能完全不一样——有些人的代码风格简洁得让你拍大腿有些人的思路和你有本质区别。这种对标能迅速帮你找到自己的盲区。最后再分享一个我个人的心得体会算法竞赛这条路天赋确实有影响但远没有到决定性的程度。就我接触过的大量选手来看最终拉开差距的更多是持续投入的时间、科学的训练方法以及在瓶颈期不放弃的韧性。如果你能按照循序渐进的路线保证每天的练习量并且每次都尽量把一道题吃透而不是囫囵吞枣那么半年到一年左右看到明显的水平跃迁是非常现实的目标。愿你在这条路上既收获名次和奖项也收获那种“把一个复杂问题拆解到无懈可击”的思维乐趣。