
2023蓝桥杯B组初赛这个比赛我陪学生带了三年自己也下场打过两轮。你要是准备过就会知道初赛真正的难点不是题目有多深而是题量、时间、环境、心态四样东西叠在一起。很多基础不错的同学平时做题刷刷的一到正式比赛就挂在各种“看起来不算问题”的细节上提交格式错、忘注释掉测试代码、第一题填结果填错格子、DFS写爆栈出来対答案才发现只差一步。这篇东西就是把我自己备战和带人备战的完整思路整理出来按考点拆解、刷题路线、失误笔记一条条讲目标就一个让你在2023蓝桥杯B组初赛里稳扎稳打能拿的分一分不乱丢。1. 先看懂2023蓝桥杯B组初赛题型与考点全拆解1.1 十道题的结构与分值蓝桥杯B组初赛省赛整体题型基本稳定你打开模拟系统会看到一排题目从易到难排列常见构成是这样的填空题若干道直接填数字/字符串结果不需要提交代码答案唯一。编程大题若干道需要提交完整源码按测试点得分部分分给得很细。难度梯度一般是从“送分模拟”到“中等算法”再到“压轴难题”但注意梯度不是均匀的经常第二题比第三题恶心第五题比第六题简单。分值分布有个规律前面的题分值低但容易拿稳后面的题分值高但需要完整算法能力。一个小策略是——填空题别追求检查次数编程大题别一上来就死磕满分。比如一道15分的程序题你跑对60%的数据就有9分比在25分题上卡一小时划算得多。1.2 难度梯度与拿分策略我初赛那年就是吃了“前松后紧”的亏。上来两题做得很爽结果第四题复杂模拟写了半小时后面动态规划题只剩二十分钟明明想法对了却没调通。这几年拿奖学生的共同策略是这样的前二十分钟先快速浏览全部题目把“一眼有思路”的题圈出来。填空或简单编程题控制在每题10-15分钟内超过时间立刻跳过。手上有三个以上“半成品”题时优先把你有完整思路的题补完而不是纠结某一道题优化到满分。压轴题如果只有暴力思路先把暴力分了再说别直接放弃。这个比赛比的不是谁“难题做得最漂亮”而是谁“该拿的分丢得最少”把策略刻在脑子里再去做题。2. 高频考点的核心算法细节2.1 模拟与枚举不是“傻写循环”就完事模拟和枚举是B组初赛的绝对主流至少占三到四题。很多人觉得就是“照着题意敲代码”但真写起来会发现步骤繁杂、边界特别多、数据一多就超时。我给你一个比较靠谱的模拟题解法路径先把题目的操作步骤用自然语言写下来画个流程图不要拿到手就敲代码。把“变化量”抽出来比如棋盘格子的颜色状态、地图上的坐标、队列里的先后顺序想清楚每一步之后哪些变量会变。优先用结构体/类来组织状态而不是散落一堆平行数组否则后面debug会哭。枚举题先想清楚枚举对象——是枚举起点、枚举区间还是枚举所有可能取值再看能不能剪枝。我之前写过一个日期类的模拟题给定一个年份输出这一年所有“星期五且是13号”的日期。第一版我直接枚举每一天判断星期几跑是能跑但慢得离谱而且代码特别丑。后来改成从已知的某一天星期几推导出偏移量再根据每月天数计算13号是星期几代码量少了三分之二运行时间直接可忽略。枚举的优化技巧也差不多。比如求一段区间内满足某个条件的数如果区间上限是10的9次方就别一重循环到底想想能不能按位枚举或者拆成“前缀答案相减”。2.2 动态规划与搜索状态设计才是灵魂B组初赛的压轴题通常落在动态规划DP和搜索上。搜索题十有七八是DFS或BFS只要你递归边界处理得干净拿部分分很容易。DP题则是区分度最大的题型很多人卡就卡在“知道这题要用DP但状态不会设”。我的经验是遇到DP先问三个问题这个问题是“取还是不取”“走还是不走”的决策题吗我能不能把过程拆成阶段每个阶段只依赖前一个阶段状态能不能用一个或两个整数表示比如dp[i]表示前i个物品的最优值dp[i][j]表示走到第i行第j列的最优值。举个很常见的场景背包问题的变种。题目说有一堆物品每件有重量和价值背包容量有限要求价值最大。这就是典型dp[j]表示容量为j时的最大价值物品循环在外层容量循环从大到小。但很多变种会坑你一下比如物品可以选多次那容量循环就从前往后。搜索题也一样状态定义决定效率。比如走迷宫求最短路径BFS的队列里如果存坐标每步扩展四个方向复杂度没问题但如果你把走过的路径整个存在队列节点里内存立刻爆炸。正确做法是开一个vis数组记录步数。就这么一个小细节决定你是拿满分还是运行错误。DFS的坑主要在“恢复现场”。我自己就写过递归回溯搜索所有排列忘记在递归返回后把标记数组重置结果数值越来越大最后所有答案都是错的。所以要养成习惯递归前标记递归后立刻取消标记。2.3 STL的正确打开方式暴力党和STL熟练党的差距到了初赛就会体现得很明显。同一个“统计连续相同字符”的题有人用双重循环卡边界有人一行unique加字符串处理就搞定代码又快又不容易错。C选手至少把这几个容器和算法摸熟vector动态数组注意resize和push_back混用的坑。queue/stack/dequeBFS、单调队列都用得上。set/map需要去重或统计频率时很好用但注意操作复杂度是O(log n)。sort 自定义cmp很多排序题直接秒。next_permutation/prev_permutation全排列相关题一句函数解决。lower_bound/upper_bound二分查找尤其适合边界处理。但STL也不是万能的有两个常见坑。一是map默认按key排序如果你需要按value排序或按插入顺序得自己额外处理。二是sort不是稳定排序如果你需要“相等时按输入顺序输出”得用stable_sort或者给每个元素带上编号。另外别在比赛现场临时试新函数。你要做的准备工作之一就是提前把常用STL用法敲一遍确认自己的记忆没问题。我有一次想当然用了vectorint a(n, 0)结果n是负数数据输入问题程序直接崩了后来才反应过来应该先检查输入范围。3. 备赛路线与刷题方法3.1 从语法到题感的三阶段路线很多同学问我“还有一个月/两周/三天怎么准备”我的回答永远是不同阶段做不同的事。阶段一语法唤醒1-3天。如果你已经学过C或Java不要再看语法书从头看了直接刷“字符串处理数组操作简单模拟”的题遇到不会的函数现查。这个阶段是把脑子里的语法碎片重新激活。阶段二高频算法专项一周以上。按“枚举→模拟→二分→搜索→DP→数论基础”的顺序每个专题刷10-20道题。刷的时候不要追求量而是把每一题的“为什么这样设计状态/循环/边界”想明白。这个阶段决定了你的上限。阶段三整卷模拟最后两周。固定用一个下午严格按比赛时间做整套题。目标两个训练时间分配、暴露环境操作问题。我第一次模拟的时候就发现自己会在“确认提交”页面犹豫很久白白浪费五分钟。后来我给自己定了个铁律——检查一遍就交除非发现致命bug否则不改。3.2 每道题要过三遍错题与复盘我认识一个拿省一的选手他刷题数量不是最多的但他有个习惯每道核心题刷三遍。第一遍不看题解硬做做不出可以看提示但必须自己写完整。第二遍隔两天再做重点看自己能不能写出更短的代码。第三遍考前一周只用眼睛过一遍在脑子里跑流程。三遍的意义在于把“看懂了”变成“会做了”。很多时候你对着题解觉得“哦原来如此简单”合上书自己写就卡住——这就是欠练。特别是DFS回溯、DP状态转移这种思路和代码的差距比你想象的大得多。复盘时用表格记下面几个问题题目类型我的思路卡住的点正解的关键能不能推广到其他题模拟题直接循环模拟边界处理不清用哨兵节点简化判断这类题先画流程图这个表格看着简单但对考前复习价值极高。你最后一周不需要把几百道题重新刷一遍把表格翻一遍回顾每个关键点和错误效率远高于盲目刷题。3.3 典型题实例一个“看着像数学实则是DP”的拆解我拿一个自己准备时觉得很有代表性的题来拆解。题目大概是一个长度为n的数列你可以从左到右依次决定每个数保留还是删除但要保证保留的数严格递增问最多能保留多少个。很多人第一反应是“最长上升子序列”套O(n²)的DP模板能过一部分数据。但如果n到了10的5次方就必须换成二分优化版的贪心DP。整个过程是这样想的定义dp[i]表示长度为i的递增序列末尾最小可能值这个值越小越好。遍历每个数用二分查找找到第一个大于等于它的位置更新dp。最后看dp数组的长度即为答案。写出来代码不长但难在状态含义的转换。你要是第一次接触八成会问“为什么可以这么玩”而不是直接背代码。我建议你把原数列和dp数组的变化过程手写在草稿纸上走一遍样例比看十遍讲解都管用。做题的时候先把暴力版本写上保证正确再优化。暴力版本拿到30%的分优化版本再拿剩下的分两段代码分开提交避免改坏了全军覆没。4. 考场实战那些坑过无数人的细节4.1 环境与提交的“隐形陷阱”每年初赛都会有一批人挂在环境细节上非常可惜。我总结几个最容易踩的代码模板没提前准备。正式比赛系统允许你提前准备代码模板包括快读、常用头文件、自定义类型定义。如果你在考场里现敲#include和ios::sync_with_stdio(false)就是在浪费时间。测试完忘了删调试输出。这个是最蠢但最常见的错误没有之一。用cout debug定位完问题交之前一定要全删干净或者用注释包起来。否则提交上去输出了一堆多余内容判题直接WA。输入文件名/输出文件名。蓝桥杯和很多在线判题不一样它不要求从文件读入而是标准输入输出所以不用管文件操作。但要看清题目有没有特别说明我遇到过题目要求输出“Case #1:”这种前缀忘写了直接格式错误。数组开小了。贪图省内存把数组开到刚好N结果题目数据范围是N1运行错误。一般要养成开大一点的习惯比如N是100000数组就开100005或者稍微留点余量。4.2 时间分配与检查顺序我自己的时间表是这样的你可以参考修改开考前5分钟读全部题目标记简单/中等/难。前60分钟做所有“简单题”。第60-120分钟做中等题目标是拿到70%-90%的分数。第120-150分钟回头处理难题的暴力分。最后30分钟全局检查重点查格式、是否多输出东西、数组越界。这套流程的核心思想是“先保底再攻坚”因为难题你要么分布了思路要么就算再给一小时也未必写得对。与其纠结最后一道25分题不如把前面每一道题都送到“稳”的状态。检查顺序也有讲究从后往前检查因为你刚做的题印象最深反而容易顺着自己的思维误区走。我好朋友这次初赛就是检查时按顺序看第一题扫了一眼觉得没问题结果题目问“输出最小值”他写成“输出最大值”——这个错误哪怕认真读一遍题目都能发现但他愣是没看出来考完对了下答案才发现。4.3 超时与溢出的排查技巧超时是个让人头大的问题。本地运行快得很一提交就TLE。常见原因有一个很隐蔽用了endl而不是\n。endl会强制刷新缓冲区大量输出时性能差别非常大。另外一个坑是死循环或者指数级增长。比如DFS没写好终止条件输入一大就跑不完。遇到超时先不要急着优化复杂度先用一个小数据测一下确认程序能正常结束再看是不是复杂度太高。溢出也一样。注意int的范围是大概21亿如果你的变量可能累加到超过这个数直接换long long。特别是那些模运算题先乘后取模很容易溢出所以每一步都要取模或者用大类型。调试的时候写一个“非常规输入测试”的习惯很管用。比如输入最大值、输入0、输入负数。有一次一个判断“两数之差是否大于1”的题我没考虑差值为负数结果差为-2时也判成了“大于1”全程错误。加一行绝对值就好了。5. 考前一周的实操细节5.1 把模板和常用代码准备好我考前会用一晚整理自己的“现场速查笔记”。这里分享下我的分类常用头文件写法C的bits/stdc.h在部分环境可能不支持保险起见用具体的头文件组合。快读模板处理大量整数输入时明显加速。常用算法的核心代码骨架二分答案、DFS/BFS、最短路径简单版、并查集、背包DP。常见错误自查清单数组大小、类型范围、初始化、多组数据重置。注意模板不需要写成完整能跑的类库而是每段10-20行的“骨架”你在考场上根据题目改成完整代码。比如DFS骨架void dfs(int step, int state) { if (step n) { // 到达目标 updateAnswer(state); return; } // 尝试每一步的选择 for (int option : choices) { if (valid(option)) { // 标记 dfs(step 1, newState); // 撤销标记 } } }这种骨架的价值不是直接抄而是让你回忆“这个算法长什么样”省去现场大脑短路。总结模板的时候顺便也把对应的复杂度写旁边比如“这个版本的DFS状态数是O(n!)n10可以跑n20必须剪枝”提醒自己别在数据范围很大时用暴力。5.2 最后一天只做“热身”不碰“难题”考前一天不需要再大量刷题。做过多的新题只会让你焦虑并且容易在某道题上卡住影响自信。我的建议是找两三道自己做过且完全掌握的简单题快速写一遍保持手感。把上面说的现场速查笔记再翻一遍。把比赛用的编译环境提前运行一下确认能用检查编译器版本、代码提示有没有开、配置文件会不会自动保存为其他格式。早点睡别熬夜。初赛上午场的状态直接影响你的思考速度。我还见过一个办法挺好用的睡前在脑子里把“比赛开始——读题——写第一道题——提交”整个流程过一遍。这叫心理预演很多运动员也会用目的是让正式场景在下意识里变得熟悉减少紧张感。别看这个细节不起眼考场上心态稳比多会一个算法更实在。算起来我自己从第一次参加到后来拿省一走了一年多弯路就是反复在刷题量和刷题质量之间摇摆。最后总结出最值钱的三个字复盘、复盘、复盘。题目做出来只是第一步把为什么能A做出来为什么B会卡住下次怎么不卡写下来比赛前看三遍比临时抱佛脚刷一百道题都有用。希望这篇笔记能帮你在2023蓝桥杯B组初赛里少踩几个坑稳稳把该拿的分拿回来。