
目录
前言
相信很多朋友都报名了2023年的蓝桥杯吧,为了准备今年的蓝桥杯,今天带大家回味一下去年的蓝桥杯,文里的题解都是我当时考场代码或者赛后补题代码,可能会有些不合理的地方,欢迎大家提意见!
下面我们开始吧!!
A.九进制转十进制
题目:
9进制整数
转换为10进制等于多少? 九进制数2022
输入:
无
输出:
写个程序直接输出结果即可。
问题解析:
签到题,考验进制的转换,而且还是转换成较容易转换的十进制。而且数值比较小,可以直接用计算器计算得出结果。

代码:
注意本题是填空题!代码要求直接输出答案,不要输出多于内容,如下:
1 |
|
B.顺子日期
题目:
小明特别喜欢顺子。顺子指的就是连续的三个数字:123,456等。顺子日期指的就是在日期的
yyyymmdd表示法中,存在任意连续的三位数是一个顺子的日期。例如 20220123 就是一个顺子日期,因为它出现了一个顺子:123。而 20221023则不是一个顺子日期,它一个顺子也没有。小明想知道在整个2022年份中,一共有多少个顺子日期。
输入:
无
输出:
写个程序直接输出结果即可。
问题解析:
签到题,但这个题在去年刚参加完的时候有异议,那就是012是不是顺子,我当时比赛的想法是012也是顺子的。题目本身不难,是蓝桥杯喜闻乐见的日历题,可以写代码也可以对着日历看!
因为前四位2022是确定的,而月份没有第34月,所以如果是顺子日期,则必然是后四位中有顺子,只有在第1,10,11,12月的日期可能满足这个条件,所以我们思考这几个月即可。可以对照日历也可以找出顺子日期。
分别为20220120,20220121,20220122,20220123,20220124,20220125,20220126,20220127,20220128,20220129,20221012,20221123,20221230,20221231共14个。
代码:
注意本题是填空题!代码要求直接输出答案,不要输出多于内容,如下:
1 |
|
C.刷题统计
题目:
小明决定从下周一开始努力刷题准备蓝桥杯竞赛。他计划周一至周五每天做a道题目,周六和周日每天做b道题目。请你帮小明计算,按照计划他将在第几天实现做题数大于等于n题?
输入:
10 20 99
输出:
8
评测用例规模与约定:
对于50%的评测样例,
1≤a、b、n≤10⁶ 对于100%的评测样例,
1≤a、b、n≤10¹⁸
问题解析:
签到题, 基本没有太多坑的一道题,要注意题目中大于等于,并且评测样例要求10的18次方,需要开longlong。
代码:
70%做法(直接暴力):
1 |
|
不断循环每一天,根据星期几来加对应的题目,但数据过大时循环的天数可能很多,很容易就会超过规定时间 。
100%做法:
1 |
|
只需要一点很小的优化就可以省去大部分时间,先求整星期,再求具体天数。
D.修剪灌木
题目:
爱丽丝要完成一项修剪灌木的工作。
有 N 棵灌木整齐的从左到右排成一排。爱丽丝在每天傍晚会修剪一棵灌木,让灌木的高度变为 0 厘米。爱丽丝修剪灌木的顺序是从最左侧的灌木开始,每天向右修剪一棵灌木。当修剪了最右侧的灌木后,她会调转方向,下一天开始向左修剪灌木。直到修剪了最左的灌木后再次调转方向。然后如此循环往复。
灌木每天从早上到傍晩会长高 1 厘米, 而其余时间不会长高。在第一天的早晨, 所有灌木的高度都是 0 厘米。爱丽丝想知道每棵灌木最高长到多高。
输入:
3
输出:
4
2
4
评测用例规模与约定:
对于 30% 的数据,N≤10;
对于 100% 的数据,1< N ≤10000。
问题解析:
签到题, 因为这道题的解法比较好想,在这里就不写直接暴力模拟每一天的代码了,直接说优化解法。
首先我们从最容易想的两个点说起,即左右两个端点,很容易想到最左端的灌木最长的时刻,即爱丽丝从最左到最右,再从最右回到最左的那一刻,同理最右端点也是如此。
以此类推,对于中间的点,我们先判断他对于最左或者最右哪个距离更长,因为每天增长一厘米,我们可以抽象理解为爱丽丝走一个距离即增长一厘米,直接用长距离×2即为所求。
代码:
100%做法:
1 |
|
当然这其实是一个左右对称的过程,只求一半也可以,但求全过程时间也完全不会超。我建议大家在比赛的时候选择更加稳妥的写法。
E.X 进制减法
题目:
进制规定了数字在数位上逢几进一。
X 进制是一种很神奇的进制,因为其每一数位的进制并不固定!例如说某种 X 进制数,最低数位为二进制,第二数位为十进制,第三数位为八进制,则X进制数321转换为十进制数为 65。
现在有两个 X 进制表示的整数 A 和 B,但是其具体每一数位的进制还不确定,只知道 A 和B 是同一进制规则,且每一数位最高为 N进制,最低为二进制。请你算出 A−B的结果最小可能是多少。
请注意,你需要保证 A 和 B 在 X 进制下都是合法的,即每一数位上的数字要小于其进制。
输入:
第一行一个正整数 N,含义如题面所述。
第二行一个正整数 Ma,表示 X 进制数 A 的位数。
第三行 Ma个用空格分开的整数,表示 X 进制数 A 按从高位到低位顺序各个数位上的数字在十进制下的表示。
第四行一个正整数 Mb,表示 X 进制数 B的位数。
第五行 Mb 个用空格分开的整数,表示 X 进制数 B 按从高位到低位顺序各个数位上的数字在十进制下的表示。
请注意,输入中的所有数字都是十进制的。
1
2
3
4
5 11
3
10 4 0
3
1 2 0
输出:
输出一行一个整数,表示 X 进制数A−B的结果的最小可能值转换为十进制后再模 1000000007 的结果。
94
样例说明:
当进制为:最低位 2 进制,第二数位 5 进制,第三数位 11 进制时,减法得到的差最小。此时 A 在十进制下是 108,B 在十进制下是 14,差值是 94。
评测用例规模与约定:
对于30%的数据,
N≤10,M下标a、b≤8 对于100%的数据,
。 N、M与A、B的范围
问题解析:
去年考场上看到这个题是蒙b的,题是在太长,来回看了好几遍题才看懂题意。现在我们来一点一点分析。
首先我们可以知道的是,题里面给了我们一个定义:X进制数,他的每一位数进制都是不一样的,并且给我们举了一个例子,X进制数321(从低位到高位分别为2,10,8进制)转化为十进制数为65。我们先来解释一下这个转换,
3*(10*2)+2*2+1=65
很容易发现,将X进制数转化为十进制数,就是将每一位的数乘以所有低于他数位的数制。
例如3在第三位,转化为十进制数就要将3乘以第一和第二位的数制,即2,10。将每一位数都如此计算,最后相加即为10进制数。
下面用到了贪心思想:欲使A-B最小,只需使得各位数字取得合法范围内的最小进制即可,具体做法就是对A和B中相同数位的数字取maxn,该位的合法最小进制即为max(maxn + 1, 2),因为最小进制不能小于2;而对于X进制的数来说,合法的最大数字是X-1,例如8进制中最大数字是7,二进制中最大数字是1。
样例分析:
最低位 0,0 二进制。
第二位 4,2 五进制。
第三位 10 ,1 十一进制。
结果为:(10*5*2+4*2)-(1*5*2+2*2)=94。
思路正确,下面我们用代码实现即可。
代码:
30%做法(直接暴力):
1 |
|
就是对上面思路的直接暴力模拟,这个代码不过多进行解释了,时间复杂度不合理,而且两个数很大,即使开longlong也会爆。
100%做法(累乘,每一步都取mod):
1 |
|
通过累乘求出每个数位的权来减少时间复杂度。
通过开longlong和步步取模来防止溢出,注意最后结果可能为负,但根据题意,负数显然没有意义,所以先加mod再对mod取模,就可以防止负数出现。
F.统计子矩阵
题目:
给定一个 N×M 的矩阵 A,请你统计有多少个子矩阵(最小 1×1,最大 N×M) 满足子矩阵中所有数的和不超过给定的整数 K?输入:
第一行包含三个整数 N, M和 K。
之后 N 行每行包含 M 个整数,代表矩阵 A。
3 4 10
1 2 3 4
5 6 7 8
9 10 11 12
输出:
一个整数代表答案。
19
样例说明:
满足条件的子矩阵一共有 19,包含:
- 大小为 1×1 的有 10 个。
- 大小为 1×2 的有 3 个。
- 大小为 1×3 的有 2 个。
- 大小为 1×4 的有 1 个。
- 大小为 2×1 的有 3 个。
评测用例规模与约定:
对于 30% 的数据,N,M≤20;
对于 70% 的数据,N,M≤100;
对于 100% 的数据,1≤N,M≤500,0≤
≤1000,1≤K≤250000000。 A下标i,j
问题解析:
题目本身很容易理解。
因为矩阵本身没什么规律,题目本质是要求出所有子矩阵的和进行比较, 运用前缀和的思想。
可套用求子矩阵和,前缀和模板:796. 子矩阵的和 - AcWing题库
代码:
70%做法(子矩阵的和):
1 |
|
后面数据过大,四重循环显然会超时。
100%做法(双指针优化):
1 |
|
用双指针省去时间复杂度。
G.积木画
题目:
小明最近迷上了积木画,有这么两种类型的积木,分别为 I 型(大小为 2 个单位面积)和 L 型(大小为 3 个单位面积):
I型与L型积木 同时,小明有一块面积大小为 2×N 的画布,画布由 2×N 个 1×1 区域构成。小明需要用以上两种积木将画布拼满,他想知道总共有多少种不同的方式?
积木可以任意旋转,且画布的方向固定。
输入:
输入一个整数 N,表示画布大小。
3
输出:
输出一个整数表示答案。由于答案可能很大,所以输出其对 1000000007 取模后的值。
5
样例说明:
五种情况如下图所示,颜色只是为了标识不同的积木:

评测用例规模与约定:
对于所有测试用例,1≤N≤10000000。
问题解析:
状压dp,场上看到这个题目,就想到 291. 蒙德里安的梦想 - AcWing题库
这个知名的状态压缩dp题(如果不知道状压dp建议先去了解),而且积木画题目中的画布为2*N,完全可以对积木出现的方式直接进行枚举。
既然是动态规划,其核心就是假设已知其中一个状态,求另一个状态的值。这种又被称为状态转移。
dp[i][j]题目给出的状态转移的合法条件为:前i-1列已摆好,当前摆第i列,第i列是j的所有方案。
dp问题的核心是假设已知其中一个状态,求另一个状态的值。这种又被称为状态转移。
每当我们需要状态转移时,都要先考虑一个问题:状态转移是否合法?
根据题意,合法的意义即摆积木不能重叠。
先假设第i列状态如下:

当i-1列摆放完之后,我们可以看到在这种情况下,第i列没有被伸出来的积木块覆盖。
如果用0表示没有被覆盖,1表示被覆盖,那么我们可以称这种情况为00
那么,在00的基础上,我们可以在i上进行四种不同方式的积木摆放,如下:

对应i+1列为00

对应i+1列状态为10

对应i+1列状态为01

对应i+1列状态为11
那么我们可以得到一个状态转移结论:
假如j当前为00,那么对应的下一列的状态可以为:00,01,10,11
同理,假如i当前为10,那么对应的下一列的状态可以为01, 11,如下:


假如i当前为01,那么对应的下一列的状态可以为10, 11,如下:


假如i当前为11,那么下一列的状态只能为00
(因为第i列什么也不能放了,所以第i+1列一定是空的)
此时我们已经判断出了所有的状态转移情况,此时我们建立一个二维数组进行存放
(第一维表示初状态,第二维表示目标状态,1表示可以转化,0表示不能转化)
1 | int g[4][4]={ |

知道了状态转移,我们就可以写出dp了:
还记得我们的dp[i][j]的定义吗,前i-1列已经摆好,有几种可能,使得第i列情况是j
dp[i][j]中存的数字即为这个可能的事件数,容易知道,j一共只有四种可能(00,01,10,11)我们需建立一个dp[N][4]
100%做法(状压dp):
1 |
|
循环j,k来判断 dp[i+1][k]=(dp[i+1][k]+dp[i][j]*g[j][k])%mod;
如果能从j转移到k,就把第i列状态为j的方案数加到第i+1列状态为k的方案集合中去,实现状态转移。
H.扫雷
题目:
扫雷·题目
输入:

2 1
2 2 4
4 4 2
0 0 5
输出:
输出一个整数表示答案。
2
样例说明:

评测用例规模与约定:

问题解析:
看到这题人麻了
首先看到雷爆炸会带动周围其他雷爆炸,很容易想到要用bfs算法来解决
但x,y的数据范围过大(10^9)用数组肯定是会爆的,只能用哈希。
一说到哈希,很容易想到利用c++自带的map和unordered_map来进行储存,但很遗憾,map的速度太慢,没有办法过掉全部测试点,只能用手写哈希的方式来储存。如果对哈希不了解,可以看一下840. 模拟散列表 - AcWing题库
下面来针对这个题目讲解一下具体的哈希方法:
首先,因为x,y的数据范围一样大,我们可以把x,y映射到一个唯一的哈希值,
即为:x*(1e9+1)+y, 这是一个(1e9+1)进制数,可以把这个哈希值近似看成一个数字 :xy
注意事项:首先哈希表的长度至少为2n,在这里我们开的越大越好,这样可以避免哈希冲突。
哈希表的key和value,哈希表的value即我们刚刚通关计算得到的数字xy,在获取哈希值之后,我们还要将他储存在哈希表的某一个位置,这个位置即为key,我们将刚刚得到的哈希值对哈希表取模即可得到key。如果发生了冲突,就需要从这一点往后遍历,直到找到第一个空闲的位置
100%做法(哈希,bfs):
1 |
|
代码中bfs的部分没有做详细解释,可以做一些经典的bfs题学习一下!
I.李白打酒加强版
题目:
李白打酒·题目
输入:

5 10
输出:
输出一个整数表示答案。由于答案可能很大,输出模 1000000007 的结果。
14
样例说明:
如果我们用 0 代表遇到花,1 代表遇到店,14 种顺序如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 010101101000000
010110010010000
011000110010000
100010110010000
011001000110000
100011000110000
100100010110000
010110100000100
011001001000100
100011001000100
100100011000100
011010000010100
100100100010100
101000001010100
评测用例规模与约定 :

问题解析:
经典李白打酒,很明显的一道dp题。
还记得dp的两大要点吗?状态和转移
状态:题目中有三个状态需要我们注意,分别是店,花,酒,在考虑整体状态的时候需要全部考虑进去,所以我们设dp[i][j][k],表示经过了i个花,j个店,手里还有k个酒的的方案总数。
转移:有两种情况,第一种是上一个经过了花,第二种是上一个经过了店,显然状态转移方程就是:
dp[i][j][k]=dp[i-1][j][k+1]+dp[i][j-1][k/2]
100%做法(dp):
1 |
|
个人认为比积木画简单
J.砍竹子
题目:
砍竹子·题目
输入:

6
2 1 4 2 6 7
输出:
一个整数表示答案。
5
样例说明:
其中一种方案:
1
2
3
4
5
6 2 1 4 2 6 7
→ 2 1 4 2 6 2
→ 2 1 4 2 2 2
→ 2 1 1 2 2 2
→ 1 1 1 2 2 2
→ 1 1 1 1 1 1
需要5步完成
评测用例规模与约定:

问题解析:
首先我们需要关注的是,只能对连续一段高度相同的竹子使用魔法
将这一段高度变为
我们不禁思考,这样的变化最多能进行几次,经过计算,1e18在经过6次变化后就会变为1,也就是说所有的数最多经历6次变化。
这道题主要考查我们的思维,我们把每个数字,在经历变化,最终变成1的过程,抽象为层,比如说1e18,他有6层,每层都有一个数字,逐渐减小,最终为1。
假如我们把所有数字单独隔离开,独自层层减少,可以得到一个总数,但这显然不是我们的答案,因为当一个数字的邻居和他相同时,可以一起减小,省去一次魔法。
那如果我们能找到所有数字及他们每一层的数字,整体进行比较,如果发现有相邻的情况,就让总魔法使用数减一,是不是就可以解出来了呢。
100%做法(思维):
1 |
|
看到还有线段树,优先队列等做法,可以去学习一下(
最后,祝大家在2023年蓝桥杯中能取得自己满意的成绩!!!
校订记录(2026-10-09):本页从原文迁入后,在“李白打酒加强版”的遇花状态转移中补充 k+1<N 边界判断,避免读取数组末尾之外的元素。该示例通过未定义行为检查,输入 5 10 仍输出 14;其余解法与原文日期保留,未重新核验整套题的评测结果。参考:C++ 标准工作草案的数组下标与指针运算范围。










评论
评论
留言服务尚未连接。
正在打开留言簿……