
1. 赛题整体复盘与难度定位1.1 那一届到底考了什么第九届蓝桥杯省赛CB组这套题我前后完整做过三遍第一遍是在赛场上后两遍是赛后带学弟学妹复盘。整体感受就一句话填空题送分编程题分层最后两题卡人。这套卷子的题型分布非常典型六道填空加四道编程填空里前几道基本是手算或者简单枚举就能出结果编程题从第三道开始明显上强度尤其是最后那道跟区间和前缀思想相关的题当年赛场上能完整写出来的人不多。先把这套题的骨架列出来方便你对号入座题号题型核心考点难度体感第1题填空日期计算 / 天数累加入门第2题填空进制转换 / 数位处理入门第3题填空大数乘法 / 数组模拟中等偏易第4题填空容斥原理 / 枚举中等第5题填空快速幂 / 取模运算中等第6题填空递归 / 搜索中等偏难第7题编程模拟 / 排序中等第8题编程贪心 / 区间处理中等偏难第9题编程搜索 / 剪枝难第10题编程前缀和 / 差分思想很难这张表是我自己复盘时整理的难度体感是相对的对于刚接触算法竞赛的同学来说第7题往后可能都会觉得吃力。但好消息是蓝桥杯省赛的评分机制是按测试点给分不是全有全无所以哪怕你写不出最优解暴力枚举也能拿到一部分分数。这一点非常关键后面我会专门讲怎么骗分。1.2 为什么这套题值得反复研究很多人做完真题对完答案就扔了我觉得挺可惜的。这套题的价值不在于题目本身有多难而在于它几乎覆盖了省赛阶段所有高频考点日期模拟、进制转换、大数运算、容斥、快速幂、递归搜索、贪心、前缀和。你把这十道题吃透基本上省赛范围内不会再遇到完全陌生的题型。而且这套题的命题风格很蓝桥——不追求算法的高级感但特别看重边界处理和代码实现的细致程度。很多同学思路对了但边界没考虑全测试点过不全最后分数很难看。我带过一个学弟第10题思路完全正确前缀和加差分但数组开小了直接爆栈一分没拿到。这种教训比任何教科书都深刻。另外这套题里有一道关于乘积末尾零的填空题当年争议挺大很多人算错了。我在后面会详细拆解这道题的坑在哪里以及为什么那么多人会掉进去。2. 填空题逐题拆解与手算技巧2.1 日期类填空题别急着写代码第一题是典型的日期计算题问某两个日期之间相隔多少天或者某个日期是星期几。这类题我的建议是先手算再用代码验证。为什么因为手算能帮你建立对问题的直觉而且考场上手算往往比写代码快。具体怎么做以从某年某月某日到另一年某月某日有多少天为例手算的核心是分段先算起始日期到当年年底的天数再加上中间完整年份的天数注意闰年最后加上目标年份年初到目标日期的天数闰年的判断规则是能被4整除但不能被100整除或者能被400整除。这个规则一定要记牢考场上没有时间让你推导。注意蓝桥杯的日期题经常在是否包含起始日和是否包含结束日上做文章读题时一定要看清楚是从A到B经过多少天还是A和B之间有多少天这两个答案可能差一天。我当年做这类题的习惯是手算完之后写一个几行的代码验证一下代码用最笨的循环逐天累加虽然慢但绝对不会错。反正填空题只看最终结果过程不重要。2.2 进制转换与数位处理小心前导零第二题涉及进制转换或者数位统计。这类题的坑主要集中在两个地方前导零的处理和进制的边界。举个例子如果题目问在某个进制下某个数的表示中有多少个某数字你需要注意这个数在该进制下的最高位不可能是零但中间和低位可以是零。很多人写循环的时候从低位往高位取取完就统计结果把不该算的零也算进去了。我的做法是先把数转换成目标进制的字符串然后再统计。转换的代码很固定string toBase(int n, int base) { if (n 0) return 0; string s; while (n 0) { int d n % base; s (d 10 ? 0 d : A d - 10); n / base; } reverse(s.begin(), s.end()); return s; }这段代码你直接背下来都行考场上能省不少时间。注意处理n等于0的特殊情况很多人会漏掉。2.3 大数乘法数组模拟的经典套路第三题是大数乘法两个超出long long范围的数相乘。C里没有内置的大数类型所以只能用数组模拟。核心思路就是小学竖式乘法用一个数组存结果双重循环逐位相乘注意进位。代码框架如下vectorint multiply(vectorint a, vectorint b) { vectorint res(a.size() b.size(), 0); for (int i 0; i a.size(); i) { for (int j 0; j b.size(); j) { res[i j 1] a[i] * b[j]; } } for (int i res.size() - 1; i 0; i--) { res[i - 1] res[i] / 10; res[i] % 10; } return res; }这里有个细节结果数组的长度开成两个乘数长度之和这是最坏情况下的位数。进位从后往前处理最后去掉前导零。实操心得大数乘法最容易错的地方是进位处理的方向。一定要从低位往高位进位也就是从数组末尾往开头。我见过有人从前往后进位结果全乱了。2.4 容斥原理画个韦恩图再动手第四题考容斥原理通常是问1到N中有多少个数能被a或b或c整除这类问题。公式很简单|A∪B∪C| |A| |B| |C| - |A∩B| - |A∩C| - |B∩C| |A∩B∩C|但考场上紧张的时候容易漏项或者符号搞错。我的建议是先在草稿纸上画三个圈标清楚每个区域然后再写代码。代码实现就是枚举所有非空子集奇数个集合的交集加偶数个集合的交集减。int solve(int n, vectorint nums) { int m nums.size(); int ans 0; for (int mask 1; mask (1 m); mask) { long long lcm 1; int bits 0; for (int i 0; i m; i) { if (mask (1 i)) { bits; lcm lcm / __gcd(lcm, (long long)nums[i]) * nums[i]; } } if (bits % 2 1) ans n / lcm; else ans - n / lcm; } return ans; }注意这里用的是最小公倍数而不是乘积因为集合的交集大小取决于最小公倍数。这个细节很多人会搞错。2.5 快速幂取模运算的细节第五题是快速幂求a的b次方对p取模。这个算法本身很标准但有几个细节容易翻车底数a可能大于p要先取模指数b可能很大要用long long乘法的时候可能溢出要用long long中转long long fastPow(long long a, long long b, long long p) { long long res 1; a % p; while (b 0) { if (b 1) res res * a % p; a a * a % p; b 1; } return res; }这段代码我建议默写十遍直到形成肌肉记忆。蓝桥杯几乎每届都考快速幂或者它的变种。2.6 递归搜索填空题里的搜索怎么剪枝第六题是填空题里最难的通常是一个递归或者搜索问题比如有多少种方案或者最短路径长度。填空题用搜索做最大的问题是状态空间可能很大不剪枝会超时。剪枝的核心思路有三个可行性剪枝当前状态已经不可能达到目标直接返回最优性剪枝当前代价已经超过已知最优解直接返回记忆化相同状态只算一次填空题的搜索通常规模不会太大因为出题人知道你是手算或者写小程序验证不会故意卡你。但如果你发现暴力搜索跑不出来就要考虑是不是漏了剪枝条件。提示填空题的搜索如果实在写不出剪枝可以尝试缩小搜索范围比如先算小规模的情况找规律再用规律推大规模的结果。3. 编程题核心思路与代码实现3.1 模拟与排序把题目翻译成代码第七题是编程题里相对简单的通常是模拟一个过程然后排序输出。这类题的难点不在算法而在把题目描述准确地翻译成代码。我的做法是先把题目里的规则用自然语言列出来一条一条对应到代码。比如题目说每次操作选择最大的那个你就需要一个排序或者优先队列。题目说如果有多个相同则选择编号最小的你就需要在排序的比较函数里加上编号的判断。struct Node { int val, id; bool operator(const Node other) const { if (val ! other.val) return val other.val; return id other.id; } };这种自定义排序的题目比较函数写错一个符号就全盘皆输。写完一定要用题目给的样例测一遍再自己造几个边界数据。3.2 贪心与区间处理排序是第一步第八题考贪心通常是区间调度或者区间覆盖问题。贪心题的核心是找到正确的贪心策略而大多数区间问题的贪心策略都跟排序有关。常见的排序方式有两种按右端点升序排适用于最多能选多少个不重叠区间按左端点升序排适用于合并所有重叠区间选错了排序方式贪心就不成立。怎么判断用哪种我的经验是看题目要什么。如果要最多数量通常按右端点排如果要覆盖范围通常按左端点排。// 最多不重叠区间 sort(intervals.begin(), intervals.end(), [](auto a, auto b) { return a.second b.second; }); int count 0, lastEnd -1e9; for (auto seg : intervals) { if (seg.first lastEnd) { count; lastEnd seg.second; } }这段代码是模板级别的背下来直接能用。但要注意区间的开闭问题是还是取决于题目说的是不重叠还是不相交。3.3 搜索与剪枝编程题里的搜索怎么拿分第九题是搜索题通常是DFS或者BFS。编程题的搜索比填空题的搜索规模大得多不剪枝基本不可能过全部测试点。我的策略是分层拿分先写一个纯暴力搜索不剪枝能过多少测试点过多少加上可行性剪枝通常能多过一两个测试点再加上最优性剪枝或者记忆化争取过大部分测试点如果时间允许考虑换成DP或者更高效的算法这种策略在蓝桥杯里非常实用因为测试点通常是按规模递增的小规模数据暴力能过大规模数据才需要优化。实操心得搜索题的剪枝条件要写在进入下一层递归之前而不是在递归函数开头。写在开头虽然也能剪但会多一次函数调用的开销规模大的时候差别很明显。3.4 前缀和与差分最后一题的杀手锏第十题是整套卷子最难的考的是前缀和或者差分思想。这类题的典型形式是给一个数组多次询问某个区间的和或者多次对某个区间加上一个值最后问结果。前缀和的核心公式sum[i] sum[i-1] a[i]区间[l, r]的和 sum[r] - sum[l-1]差分的核心公式diff[l] val, diff[r1] - val最终a[i] a[i-1] diff[i]这两个技巧本身不难难的是识别出题目可以用前缀和或差分。很多题目不会直接说求区间和而是包装成一个场景比如统计某个时间段内的访问量或者计算某个区域内的资源总量。// 前缀和 vectorlong long pre(n 1, 0); for (int i 1; i n; i) pre[i] pre[i-1] a[i]; // 查询[l, r] long long ans pre[r] - pre[l-1]; // 差分 vectorlong long diff(n 2, 0); // 对[l, r]加val diff[l] val; diff[r1] - val; // 还原 for (int i 1; i n; i) a[i] a[i-1] diff[i];这两段代码是必须条件反射写出来的。蓝桥杯省赛里前缀和和差分的出现频率极高几乎每届都有。4. 赛场实战策略与避坑指南4.1 时间分配填空题不能超过40分钟蓝桥杯省赛的时长通常是4小时我的建议是填空题控制在40分钟以内剩下的时间全部留给编程题。为什么因为填空题的分值相对较低而且很多题手算比写代码快。如果你在一道填空题上卡了20分钟后面编程题的时间就不够了。具体分配前3道填空10分钟内解决中间2道填空15分钟内解决最后1道填空15分钟内解决做不出就先跳过编程题每题30到40分钟最后一题留足50分钟这个分配不是死的根据实际难度调整。但核心原则是不要在填空题上恋战。4.2 暴力骗分不会做也要拿分蓝桥杯的评分机制是按测试点给分这意味着暴力解法也能拿分。我带过的学弟里有人最后一题完全不会但写了个暴力枚举过了3个测试点拿了30%的分。这30%可能就是省一和省二的区别。暴力骗分的技巧小规模数据直接枚举不优化特判一些简单情况比如n1或者所有元素相同输出一个看起来合理的答案有时候能蒙对注意骗分的前提是代码能跑通不报错。如果暴力代码都写不对那就一分都拿不到。所以平时练习的时候暴力解法也要练熟。4.3 常见翻车点速查表下面这张表是我复盘时整理的都是血泪教训翻车点典型表现预防措施数组越界段错误程序崩溃数组开大10%边界单独判断整数溢出结果变成负数涉及乘法用long long前导零答案多算或少算转换后统一处理边界条件差一错误手动测试n0, n1排序不稳定相同元素顺序错比较函数加id判断递归爆栈程序异常终止改迭代或加记忆化取模负数结果不对先加模数再取模输入格式读入错误严格按题目格式读这张表建议打印出来贴在显示器旁边每次做题前看一遍。4.4 调试技巧怎么快速定位错误赛场上没有IDE的断点调试只能靠输出。我的调试习惯是先输出中间结果确认每一步的逻辑用题目给的样例测试样例过了再自己造数据造数据要覆盖边界最小值、最大值、特殊值如果结果不对从后往前排查先看输出再看计算// 调试宏提交前记得注释掉 #define debug(x) cerr #x x endl;这个宏在本地调试的时候非常方便但提交前一定要删掉或者注释掉否则会输出到标准错误有些评测系统会判错。5. 从这套题延伸出的备赛建议5.1 省赛阶段必须掌握的算法清单做完这套题我总结出省赛阶段必须掌握的算法清单按优先级排序第一优先级必须熟练排序与自定义比较前缀和与差分快速幂与取模运算递归与简单搜索贪心策略第二优先级需要会用大数模拟容斥原理简单DP背包、最长上升子序列BFS与DFS并查集第三优先级了解即可线段树树状数组最短路算法最小生成树省赛的难度基本不会超过第二优先级把前两个优先级练熟省一稳拿。5.2 刷题方法真题怎么刷才有效很多人刷题就是做完对答案然后换下一套。这种刷法效率很低。我的方法是三遍刷题法第一遍限时模拟完全按比赛环境来不查资料不百度 第二遍不限时把第一遍没做出来的题彻底搞懂看别人的题解对比自己的思路 第三遍一周后重新做一遍只看题目不看答案检验是否真正掌握三遍下来这套题的每个知识点都会刻在脑子里。我带过的学弟用这个方法两个月从省三冲到省一。5.3 代码模板哪些必须背下来赛场上时间紧张有些代码必须条件反射写出来不能现推。我建议背下来的模板快速幂前缀和与差分并查集二分查找自定义排序大数乘法这些模板我前面都给了代码直接抄下来每天默写一遍一周就能形成肌肉记忆。提示背模板不是死记硬背要理解每一行的含义。理解了之后即使忘了某个细节也能推出来。5.4 心态调整赛场上遇到不会的题怎么办最后说一个非技术的问题心态。赛场上遇到不会的题太正常了关键是不要慌。我的做法是先跳过把会做的题全部做完回头再看不会的题尝试暴力解法如果还是不会写一个看起来合理的输出争取蒙对最后10分钟检查所有代码确认没有低级错误记住蓝桥杯是按测试点给分不是全有全无。哪怕你只会暴力也能拿到分数。所以千万不要空题空题就是零分。这套第九届的题我前前后后研究了很久每次都有新的收获。如果你正在备赛建议把这套题当作模拟卷严格限时做一遍然后对照这篇复盘把每个知识点都吃透。省赛的难度其实没有想象中那么高关键是基础扎实、边界细致、心态稳定。把这三点做到省一真的不难。