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/deque:BFS、单调队列,都用得上。set/map:需要去重或统计频率时很好用,但注意操作复杂度是O(log n)。sort+ 自定义cmp:很多排序题直接秒。next_permutation/prev_permutation:全排列相关题,一句函数解决。lower_bound/upper_bound:二分查找,尤其适合边界处理。
但STL也不是万能的,有两个常见坑。一是map默认按key排序,如果你需要按value排序或按插入顺序,得自己额外处理。二是sort不是稳定排序,如果你需要“相等时按输入顺序输出”,得用stable_sort或者给每个元素带上编号。
另外,别在比赛现场临时试新函数。你要做的准备工作之一,就是提前把常用STL用法敲一遍,确认自己的记忆没问题。我有一次想当然用了vector<int> 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,结果题目数据范围是N+1,运行错误。一般要养成开大一点的习惯,比如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!),n=10可以跑,n=20必须剪枝”,提醒自己别在数据范围很大时用暴力。
5.2 最后一天:只做“热身”不碰“难题”
考前一天不需要再大量刷题。做过多的新题只会让你焦虑,并且容易在某道题上卡住影响自信。我的建议是:
- 找两三道自己做过且完全掌握的简单题,快速写一遍,保持手感。
- 把上面说的现场速查笔记再翻一遍。
- 把比赛用的编译环境提前运行一下,确认能用,检查编译器版本、代码提示有没有开、配置文件会不会自动保存为其他格式。
- 早点睡,别熬夜。初赛上午场的状态直接影响你的思考速度。
我还见过一个办法挺好用的:睡前在脑子里把“比赛开始——读题——写第一道题——提交”整个流程过一遍。这叫心理预演,很多运动员也会用,目的是让正式场景在下意识里变得熟悉,减少紧张感。别看这个细节不起眼,考场上心态稳,比多会一个算法更实在。
算起来我自己从第一次参加到后来拿省一,走了一年多弯路,就是反复在刷题量和刷题质量之间摇摆。最后总结出最值钱的三个字:复盘、复盘、复盘。题目做出来只是第一步,把为什么能A做出来,为什么B会卡住,下次怎么不卡,写下来,比赛前看三遍,比临时抱佛脚刷一百道题都有用。希望这篇笔记能帮你在2023蓝桥杯B组初赛里少踩几个坑,稳稳把该拿的分拿回来。