
作为一名从普及组一路打上来的老选手我太清楚模拟赛这玩意儿的分量了。平时刷题是攒招式模拟赛才是真正的实战对练。看到“2020.06.06 模拟赛C组37”这个标题我第一反应就是这又是一场检验阶段训练成果的硬仗。不管你现在是刚学完基础语法的小白还是已经能熟练写深搜广搜的进阶选手模拟赛都是一面最诚实的镜子它能照出你知识体系里的窟窿、代码习惯上的漏洞甚至是考场心态上的短板。这篇文章我就基于这个模拟赛场景把普及组模拟赛从赛前准备、赛中策略到赛后复盘的全流程掰开揉碎讲清楚你拿它当一份作战手册用就行。1. 模拟赛在备赛闭环中的真正定位很多同学把模拟赛当成普通刷题打完一场对个答案就丢一边这其实把最宝贵的训练资源浪费了。模拟赛和单题练习最大的区别在于它模拟了真实赛场的时间压力、题量压力和心理压力这几点是任何单题训练都给不了的。1.1 为什么说模拟赛是知识体系的“体检报告”你刷一百道“最短路”模板题不如在一场模拟赛里被一道藏得很深的最短路题卡住一次。原因很简单单题练习时你知道这道题考什么思维是顺着算法去找题目特征但模拟赛里没人告诉你这题该用什么算法你得自己从数据范围、题目描述、操作特征里去反推。这种“逆向识别”的能力恰恰是真实竞赛中最核心的能力。拿C组37这种场次来说它不是随随便便编几道题凑数的——出题人往往会故意把不同难度的算法混在一起甚至把一道题包装成另一类题的样子。比如看起来像模拟的题实际要贪心看起来像搜索的题实际要动规。这种出题思路就是专门用来打击“只会套模板”的选手的。1.2 模拟赛场次编号背后的信息量你可能觉得“C组37”就是个普通编号但这里面有门道。“C组”通常指的是模拟赛的分组层级不同组对应的题目难度下限不一样A组往往靠近提高组难度B组覆盖普及组偏上内容C组则更贴近普及组真题难度——当然有时候平台也会把C组定位成新手练习组。这也就意味着你打C组模拟赛的成绩能比较真实地反映你当前在普及组这个区间里处于什么档位。更重要的是编号“37”说明这是一套系列赛中的一场。系列赛的价值在于它的难度曲线是经过设计的前面场次埋下的知识点可能在后面场次里以进阶形式再次出现。比如第30场考了基础动态规划到第37场就可能考动态规划加状态压缩的雏形。所以完整的系列赛记录是你复盘自己成长轨迹的重要依据。我强烈建议你保存每次模拟赛的提交记录和代码而不是打完就删。1.3 模拟赛成绩和真实竞赛水平的换算关系我得泼一盆冷水模拟赛考得好不保证真实比赛就稳模拟赛考得烂也不代表你水平真那么差。这里面的误差主要来自三个方面——题目风格差异、环境差异和心态差异。但有一点是确定的长期模拟赛成绩的中位数和你的真实竞赛水平呈强相关。单场波动可以忽略十场二十场打下来你的平均排名基本就锚定了你的段位。所以不要把一两场模拟赛的得失看得太重但一定要把整体趋势看重。我当时认识一个选手单场模拟赛经常倒数但人家坚持打了整整四十场联赛的时候直接一鸣惊人拿了一等奖。他后来跟我说输赢不重要重要的是每场他都在认真调代码、改策略。2. 普及组模拟赛题型结构与出题套路拆解普及组模拟赛的题型结构非常稳定通常就是四道题时间三小时到三小时半。稳定结构背后是有原因的出题人要保证覆盖“算法基础、代码实现、数学思维、综合应用”这几个维度所以每一道题都有它明确的定位。了解这个定位你就能在开考三十分钟内快速判断每道题的性价比从而安排时间和得分策略。2.1 T1签到题数据和模拟的主战场第一题通常是最简单的但它不是白送分的。它的定位是考查你的代码基本功够不够扎实。常见出题方向有这么几类纯模拟给你一套操作规则让你逐步执行并输出结果比如开关灯、排队叫号、字符画变换。简单字符串处理比如统计词频、替换字符串、判断回文变形。高精度入门较少大数加法、大数乘法主要考查数组进位处理。数学公式直接套用给定递推式或公式注意数据类型别溢出就行。别看T1简单它埋的坑一点不少。最常见的是边界条件操作次数是0次怎么办序列长度为1怎么办输入包含空格怎么办这些边界点恰恰是出题人测试点里最密集的地方。我见过太多选手在T1上因为没处理空串或者没考虑初始状态白丢几十分。我的建议是T1别急着一分钟写完就交写完先花两分钟专门检查边界。这一题你的目标不是“过了样例”而是“在测试点全绿之前不挪窝”。2.2 T2进阶题贪心、二分和排序的思想角力第二题开始上强度了。普及组的T2不会直接告诉你“请用贪心算法”而是把贪心藏在排序规则里或者把二分藏在“最大值最小”的描述里。这些隐晦的包装需要你做过足够多的题才能一眼识破。常见出题类型包括贪心加排序比如活动安排、任务调度、区间选点。这类题的核心是证明排序规则而不是代码本身有多难。二分答案描述里出现“求满足条件的最小值/最大值”之类的字眼数据范围又比较大比如10^5以上就可以考虑二分。简单枚举优化暴力枚举能过一半数据但要用前缀和或者双指针优化才能全过。这一类题最考验的是算法意识。我教过不少学生他们看题解的时候觉得“这很简单啊”但自己上场就是想不到。为什么因为刷题的时候他们只看题号对应章节知道这是“贪心章节”所以思维被提前锚定了。模拟赛里没有锚定这题是贪心、是二分、还是纯数学推理完全要自己判断。所以我建议平时刷题时不要按算法标签刷要按难度从乱序题库里刷重点训练这种“先识别再匹配”的能力。2.3 T3分水岭动态规划和图论初探普及组的第三题是真正的分水岭。打到这里前面的题决定你能不能拿基础分第三题决定你能不能拉开和别人差距。T3的出题方向集中在两个方面动态规划入门背包问题01背包、完全背包、线性DP最大字段和、最长上升子序列、区间DP的简单形式。动态规划题的核心难点有三个状态怎么设、转移怎么推、边界怎么定。图论基础最短路尤其是SPFA和Dijkstra的堆优化、最小生成树、拓扑排序。这一块的代码量比DP要长出错的概率也更高。动态规划这块我要多说两句——很多初学者会陷入“状态定义玄学”的泥潭。我的建议是不要凭空想状态先从数据范围猜。如果n是1000大概率两层循环的DP没问题如果n是10^5那要么是贪心要么是带优化的DP。数据范围会告诉你时间复杂度的上限这是做算法题最实用的线索之一。如果你在一场模拟赛里卡在T3超过四十分钟我建议先跳过做T4回头再补。这个策略叫“止损”比死磕到底明智得多。2.4 T4压轴题搜索优化与数学综合的角力场第四题通常最难但普及组的T4有个特点它不会完全超纲而是把多个普及组知识点综合起来或者把某个算法的优化空间压得很深。常见的方向是DFS/BFS加剪枝优化可行性和最优性剪枝是核心剪枝剪得好不好直接决定你是60分还是满分。数论综合gcd与辗转相除法、素数筛、快速幂、同余性质的灵活运用。复杂模拟题目本身就极其繁琐操作种类多、规则复杂考查的是你把逻辑理清楚、用代码干净地表达出来的能力。很多选手到T4就怂了直接放弃去看别的题。这是最大的战术失误。普及组难度体系的限制决定了T4再难也必然存在部分分的“放水点”——比如约定数据范围特别小、只有一组数据、或者答案具有明显的规律可循。你只要把暴力解法写出来就能白捡三四十分。这几分在正式比赛的排名里可能就是一等奖和二等奖的分界线。3. 赛场实战全流程从开考到交卷的节奏控制模拟赛也是赛是赛就有战术。我见过太多水平不低的选手因为节奏混乱开场四十分钟就心态崩了。这一章我完整复述一下我自己的赛场流程你可以对照着调整成适合自己的版本。3.1 开考第一轮全局扫描而非埋头苦战很多选手拿到题就从T1开始读一路往下做这其实效率不高。我的习惯是开考前十五分钟只做一件事把四道题全部读一遍。不是细读而是在草稿纸上记下每道题的大致题意、数据范围、可能的算法方向。做完这一步你会得到一张类似这样的速查表题号数据范围特征初步判断预期难度T1n ≤ 10^5模拟/简单贪心低T2涉及区间最大值最小化二分答案中T3n ≤ 1000有状态转移二维DP中高T4搜索空间极大DFS剪枝/部分分高这张表的价值在于它会告诉你时间应该往哪里砸。如果T2的判断是“二分答案”那说明复杂度能控制在O(n log n)很稳如果T4一眼看不到任何多项式做法那就优先拿暴力分。3.2 做题顺序不是顺序做题而是按性价比做题我推荐的顺序基本是T1 → T2 → T4暴力分 → T3 → 回头补T4优化。如果T3你一眼发现状态很好设可以提到T4之前。核心原则是保证所有该拿的分都拿到之前不去死磕难题。为什么把T4暴力分放在T3前面因为T4的暴力往往边际收益高——你用一个宽搜或者暴搜加简单剪枝可能十到二十分钟就搞定三十分而T3的DP正解可能要花一个半小时。同样花半小时前者收益是保底的后者收益是概率的。除非你已经笃定T3的正解思路非常清晰否则先拿稳T4的保底分。3.3 写代码阶段的纪律样例过了不一定是真过了很多人的提交策略是这样的样例过了直接交。错大错特错。样例只能证明你的程序没有语法错误甚至连逻辑错误都证明不了。比较稳妥的做法是跑完样例先别急着做下一题花两分钟用几组手造的小数据测测边界。设数组时统一多开几个位置避免越界访问。检查数据范围int 能过还是需要 long long尤其是乘法场景经常当场爆掉。如果题目说明里给了特殊约定比如“保证输入均为正整数”那就可以省略一部分防御性判断但自己造的边界测试不能省。这一套下来每次可能多花十分钟但你省下的却是“交卷后发现自己数组开小了”的崩溃体验。3.4 时间分配参考表这是一个粗略的分配方案适用于三小时场次你可以按自身强弱项调整时间段任务目标0-15min通读全部题目形成速查表15-50min完成T1并充分测试满分为目标50-80min完成T2写出正解至少拿下大部分测试点80-110min暴力T4争取部分分保底分到位110-150min攻克T3写出状态和转移能写多少写多少150-165min回头补T4优化或补T3细节能捡一分是一分165-180min全部文件检查核对确保提交无低级失误注意这个表格不是死的。如果你在T1上就卡了半小时说明你基础代码能力还没过关这种时候更要果断止损快速跳到后面拿分而不是赌气死磕到底。4. 赛后复盘这种做法比多刷三套卷子更有价值模拟赛真正的分水岭不在赛场上而在赛场外。同样打了二十场模拟赛有的人水平突飞猛进有的人原地踏步差别就在于复盘的质量。打一场不复盘等于把真题当练习册刷收获少得可怜。4.1 赛后的第一件事趁热打铁重新写题我建议当天晚上最迟不超过第二天就把四道题全部重写一遍。注意不是“看题解后复制一遍”而是对于你做出来的题关掉自己的原代码重新完整写一遍看能不能一次通过。如果卡壳了说明你的第一遍是通过“试错”过的不是真懂。对于你卡住的题先不看题解自己重试二十分钟。实在没思路再打开题解看“思路摘要”然后继续合上题解自己写。这句“先思考再借助答案但绝不抄代码”是我最想让你记住的一条实践原则。题解看懂了和自己写出来之间的距离比你想象中大得多。4.2 建立错题的原因分类体系复盘的时候不要笼统地问自己“为什么错了”要把错误拆出具体类别。按我的经验所有错题可以归入以下五类错误类型典型表现应对方案算法识别错看清了题但套错算法补刷该算法专项强化特征识别边界条件错没考虑空数据、极端值建立边界检查清单代码实现错思路对但写错了循环、数组越界练习多写完整程序而非片段复杂度预估错暴力能过小数据但超时养成估算时间复杂度的习惯心态失误因为卡题导致后面全崩专门模拟“卡题时跳题”的纪律有了这套分类你每次复盘就是在给错误打标签复盘的越多标签越规律后面备考越有针对性。4.3 对拍是复盘的终极大杀器所谓对拍就是拿你的程序跟一个暴力但绝对正确的程序在同一组随机数据下比对输出。当年我在模拟赛复盘时发现一个规律凡是我做错的题有很大概率是我“以为对但实际在某些隐藏用例上错”的题。这些错误靠样例鞭长莫及只有靠对拍才能揪出来。具体操作流程是写一个暴力程序逻辑简单粗暴但正确性有保障。写一个随机数据生成器按题目的数据范围随机生成输入。在一个循环里不断生成数据并分别跑你的程序和暴力程序。一旦输出不一致立刻保存这组数据定位逻辑差异。对拍不是竞赛做题的必需技能但是竞赛复盘的必需技能。如果你现在不会写对拍我建议你专门花一个下午把它学会。这一项技能能在后续所有赛季里持续帮你找出隐藏的致命错误。5. 高频失分点与现场排查技巧实录作为一个打过数不清模拟赛的过来人我太知道大家在赛场上最容易在哪些地方栽跟头了。我统计了我自己和我带过的选手们常见的失分点整理成一份现场排查指南你可以在每场模拟赛交卷前对着这份清单做最后体检。5.1 代码实现层面的头号问题爆int和数组越界这两个问题简直是普及组的送命题。尤其是爆int在普及组题目里极其普遍明明单个数不出界但是加法、乘法一做就出界。比如一个变量范围是10^9再加一个10^9直接变成20亿超了int约21.47亿的天花板当场变成负数然后你的贪心就全乱套了。所以我的规矩是只要看到数据范围超过10^5或者涉及乘法运算、累加操作直接无脑用 long long。虽然慢了那么一丢丢但普及组的题量根本体现不出这一点性能损失换来的是稳妥。数组越界则是另一个经典陷阱。很多人定义数组大小的时候喜欢精打细算刚好卡到题目给的最大值。可一旦循环里多访问了一个下标直接数组越界轻则读到脏数据重则运行时错误。我的习惯是数组大小一律比最大值多开10到20个单位的余量省的每次数下标。5.2 输入输出的细节对竞赛而言这真不是小事在实际的OJ上竞赛数据经常几十万行地输入。如果你用cin不加优化或者用cout不断刷新输出那即便算法复杂度是标准的也可能超时。这不是算法问题是IO开销问题。放几个我常用的标准模板配置ios::sync_with_stdio(false); cin.tie(nullptr);这两行写在 main 函数开头能把 cin/cout 的速度拉到接近 scanf/printf 的水平。如果你还是不放心干脆直接用 scanf/printf 甚至 getchar 自行解析那命中百分之百不会在IO上吃亏。但要注意别在输出的时候混用 cout 和 printf那会导致缓冲区混乱表现就是输出顺序错乱或者直接没输出。选一条路走到底。5.3 逻辑层面的死角特判和初始状态很多题目的数据范围下写了“保证输入非空”之类的字眼但有些没写。你没写特判就会白丢分。以下三种特判是普及组出场率最高的n为0或1的时候整个问题的答案是什么如果题目要求求最小值初始答案变量有没有设成足够大的数如果某个状态从头到尾不可达输出约定是什么这些细节看着小但一个测试点可能就卡在这里。我的建议是每做完一道题都花半分钟问自己这道题有没有可能为空为0为负数如果有可能我的程序扛得住吗5.4 现场调试的技巧输出调试法和注释调试法的正确用法调代码时最常见的错误就是程序输出一串答案但不知道错在哪。这时候不要盯着代码干瞪眼调试手段用起来。最朴素有效的是“中间状态打印法”——在关键变量处加输出把数组里的值、循环计数器的值打出来。对照手算的小样例一眼就能看到哪里开始跟预期不一致。调完再删掉这些调试输出千万记得清理。另一个技巧是“二分注释定位法”当你确定某个函数逻辑有问题但不确定具体是哪一行的时候先把后半段代码注释掉强制固定前半段输出再把前半段注释掉固定后半段判断。通过这种砍半式排查很快就能定位到出错行。5.5 交卷前的十分钟体检清单这里我给出一份我在模拟赛最后十分钟必做的检查清单照着它走一遍基本能杜绝低级失误检查各题的文件读写竞赛题通常要求从指定文件读入、输出到指定文件但有些模拟赛平台不用文件只用标准输入输出务必提前看清说明。检查有没有调试输出没删干净。检查数组维度是否和题目设定匹配。检查所有变量类型是否足够承载极端数据。检查最终代码是否是最新版本别把旧版提交上去了。6. 关于模拟赛备赛的几点个人心得文章写到这里技术层面的内容基本上讲透了。最后我想聊一点不太“技术”、但非常重要的心得体会算是给正在备赛的同学的一点额外建议。第一模拟赛的分数真的不能代表一切。一场打得差不说明你水平差可能只是这套题没戳中你擅长的点一场打得好也不代表你无敌了可能只是这套题正好是你练过的类型。真正有参考价值的是连续十场以上的趋势。哪怕每场只前进一名积累下来都是巨大的进步。第二每次模拟赛打完不管成绩好坏我都会强制自己写一小段比赛总结内容就三行这场有什么收获、这场暴露什么问题、下一场之前补什么。别小看这三行字它们是你备考路上最真实的方向指引。每次模拟赛前翻一翻你就能清楚地看到自己经历过什么还差什么。第三也是最关键的一点一定不要因为一场模拟赛的失利就否定自己。我见过太多选手明明水平一直在涨就因为某场模拟排位掉了开始怀疑自己、甚至想放弃信息学。这是最可惜的事情。竞赛这条路拼的是耐心和稳定性模拟赛每一次失误都是在给正式比赛排雷。你把雷都踩完了正式比赛的路自然就平坦了。希望这份从模拟赛里总结出来的实战经验能帮到你。下次拿到类似“2020.06.06 模拟赛C组37”这样的场次标题时沉着地去面对就好——读完题、定好策略、写完代码、交卷走人该拿的分数一分都跑不掉。