第十六届蓝桥杯软件赛省赛C++ A组 题解。
初次参加,80/100 分左右。
H 题没拿下,一是先前没接触过基环树(虽然问题并不出在这里,想到了用 dsu + dfs 找环),然后是赛时对最优情况没有找全,没有想清楚 quq,再接再厉叭。
bilibili 2025 蓝桥杯省赛 c++ A组 解析。
A. 寻找质数
会判质数即可,签到,答案 17609。
1 |
|
B. 黑白棋
很典型的暴力题,数一数空位的数量,有 26 个,可以直接二进制枚举了。
就是码量比较大,每种情况需要判断三个条件是否都满足,都满足的输出即可。
答案 101001010011101100010110011001100110。
(b站上有 up 主做了纯推理完成的视频,大家也可以去看看)
(没写 dfs 是因为怕 debug,写起来不方便)
1 |
|
C. 抽奖
模拟题,照着题意实现即可,需要注意的是,判断得分的时候一定要从高分往低分判,
一次抽奖最多只能获得一次积分,如果同时命中多个奖项,以积分最大的那个奖项为准。
1 |
|
D. 红黑树
不难发现,一个点的颜色,与左子树的相同,与右子树的相反,考虑先转成 0-index,然后从二进制角度做。
每次往右走,就是给二进制末尾多添一个 1,往左走就是多添一个 0。
所以二进制里有几个 1,就是往右走了几次,就是颜色翻转了几次。
如果翻转的次数是偶数,那么与根节点颜色相同为 RED,否则为 BLACK。
1 |
|
E. 黑客
注意这个数据,读入第一行的 all
,如果 all == 1
特判掉,返回 0,以免 nm 相乘为 -1,导致越界 RE。
接下来,考虑对于一组特定的 n, m,有多少种矩阵的种类。
令剩下的数个数分别为 cnt[i]
,种类数就是 $\dfrac{(nm)!}{\prod_i(cnt[i])!}$.
为了对每组 (n, m),能快速得到这个结果,先保存所有元素的 $\prod_i(cnt[i])!$ ,然后先除以总个数,再乘上实际个数即可。
然后就是怎么找到(n,m)的所有组合,直接遍历数组找 cnt 有没有记录过 nm / i 即可,最后注意一些保证不重不漏的细节就可以了。
1 |
|
F. 好串的数目
Dp,先将题目中的好串分为两类:1. 连续非递减子串 2. 两个连续非递减子串拼成的串。
记 $dp[0][i],dp[1][i]$ 分别表示以第 i 个数结尾的 1/2 类子串数目。
1 类子串的转移:
- 如果该数和前一个数连续(等于或大1),那么以该数结尾的 1 类好串的数目为前一个结尾的 1 类好串数目 +1
- 如果和前一个数不连续,那么以该数结尾的 1 类好串数目为 1 (它本身)
2 类子串的转移:
- 如果该数和前一个数连续(等于或大1),那么以该数结尾的 2 类好串的数目与以前一个数结尾的 2 类好串的数目相同。
- 如果和前一个数不连续,那么以该数结尾的 2 类好串数目 与 以前一个数结尾的 1 类好串的数目相同
最终结果为:以每个点结尾的 1,2 类好串的数目之和。
1 |
|
G. 地雷阵
先看一个圆。它在 $[0,\pi/2]$ 上覆盖的区间为 $[\alpha-\beta,\alpha+\beta]$ 。
其中 $\tan \alpha = \dfrac{y}{x}$,$\tan \beta=\dfrac{r}{\sqrt{x^2+y^2-r^2}}$ 。
处理出所有的区间后,计算未被覆盖的区间占 $[0,\pi/2]$ 的比例即可。
对区间按左端点排序,然后贪心地扫描一遍就可以了。
1 |
|
H. 扫地机器人
n 个点 n 条边的无重边无自环的连通无向图 $\to$ 基环树
(也就是在树上多加了一条边,使其产生了一个环)
第一步是找出这个环,可以考虑 dsu + dfs,在依次加入边的过程中,判断两个端点是否在一个集合中,如果是,说明这两个点都在环上,分别记为 U,V。
然后从 U 开始 dfs,搜到 V 的那条路径就是这个基环树的环。
用 cir[i]
表示环上的第 i
个点。
考虑最长的路径会在哪些情况中产生:
路径不经过环
路径经过环的若干点,进入两个不同的子树
路径经过环的所有点,进入环上一个点的两棵不同子树
其中,1 3 种情况可以一起处理掉,树形 dp 解决从该点向两颗(最大)子树延申得到的路径的最大点权和。
然后第 2 种情况是比较复杂的,首先解决环的问题,我们要在环上所有可取区间中择优选择,考虑将环倍增(这是处理环的常见手段了),这样可以比较容易的得到所有可取区间。
用 $q[i]$ 表示从 $cir[i]$ 进入子树得到的最大点权和,用 $w[i]$ 表示 $cir[i]$ 的点权。
那么就是选取 $i,j\ (j-i+1<=C)$,使得 $q[i]+q[j]+\sum_{i<k<j}w[k]$ 最大。
( C 表示环上点的个数 )
先做个前缀和 $pre[i]=\sum_{k=0}^{i-1}w[k]$。
$$
q[i]+q[j]+\sum_{i<k<j}w[k]=q[i]+q[j]+(pre[j]-pre[i + 1])
$$
令 $u[i]=q[i]-pre[i + 1], \ v[i]=q[j]+pre[j]$,即求 $u[i]+v[j]$ 最大值 $(j-C+1\le i\le j-1)$
这个做法就很多了,可以用 ST 表维护 $u$ 上的区间最大值,然后遍历右端点 $j$,这样统计出最大值,时间复杂度瓶颈在 ST 表的预处理 $O(C\log C)$。(也可以用单调队列实现这个最大值的查询)
将三种情况的答案取最大值即可。
1 |
|