2023 CSP-S 解题报告

该博客对几道算法题进行题解。包括密码锁(涉及枚举算法)、消消乐(涉及栈和哈希算法)、结构体(涉及模拟、二分和STL运用)、种树(涉及二分和贪心算法),还给出了各题的难度、解法及复杂度分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为什么,为什么,为什么小图灵说上海 135pts 就能一等?(听说似乎没了)是否为真需等待时间来揭晓。(135pts 的小蒟蒻)

感觉 T2 好欢乐,每个层次都不复杂但又能区分能力。

T3 赛时代码本质逻辑无误,主要还是对齐方式以及特殊情况的处理有误。

Update:100+35+0+0=135 是二等奖

状态:完结(11/5)

题解

所有代码:code

1. 密码锁

涉及算法:枚举
难度:普及-
解法

由于考虑到所有的密码只有 1 0 5 10^5 105 种,所以枚举所有密码,然后判断一个密码是否可以变形成若干状态即可。

复杂度 O ( 1 0 5 ) \mathcal{O}(10^5) O(105)

2. 消消乐

涉及算法:栈,哈希
难度:提高
解法
35pts

考虑区间 dp,判断每一个区间是否可以被消除。 f ( l , r ) = [ a l = a r ] ⋅ f ( l + 1 , r − 1 )    o r    [ f ( l , k )    a n d    f ( k + 1 , r ) ] f(l,r)=[a_l=a_r]\cdot f(l+1,r-1)\;or\;[f(l,k)\;and\;f(k+1,r)] f(l,r)=[al=ar]f(l+1,r1)or[f(l,k)andf(k+1,r)]

复杂度 O ( n 3 ) \mathcal{O}(n^3) O(n3)

50pts

考虑栈,可以参考这题(cf原题)的题面。固定区间左端点,然后向右不断将元素入栈,若当前元素和栈顶元素相同则弹栈顶元素。栈大小为 0 时答案统计一次。

复杂度 O ( n 2 ) \mathcal{O}(n^2) O(n2)

100pts

考虑上一个做法存在的问题:多次扫描入栈有重复信息。这里提供一种通过哈希的解决方案。从第一个开始向右不断将元素入栈,若当前元素和栈顶元素相同则弹栈顶元素。假如两个不同时刻栈内元素相同,那么中间过程是可被消除的,因此我们只要知道有多少时刻栈内元素与现在相同就行,这个可以通过 hash 和 map 实现。

复杂度 O ( n log ⁡ n ) \mathcal{O}(n\log n) O(nlogn)

3. 结构体

涉及算法:模拟,二分,STL运用
难度:提高
解法

显然,对于一个类型或一个元素,要储存的内容过多,所以用结构体表示一个类型或一个元素。值得注意的是,类型嵌套存储肯定炸空间,所以我们只存名字,然后用 map<string,Type> TypeLib 对其映射。每个操作都可以照着逻辑实现,除了最后一个可以用二分查找,其它并无思维上难点,主要考验代码力。复杂度很小,故不做考虑,详情实现看代码(变量名字已经很能说明问题了)。

4. 种树

涉及算法:二分,贪心
难度:提高+
解法

这样的题目第一反应是二分答案,顺此往下想如何写 check。显然可以 O ( n ) \mathcal{O}(n) O(n) 求出每一棵树最晚何时种,记为 t i t_i ti。进而发现本质上是决定一个排列,表示第 i i i 棵树第 p i p_i pi 天种,满足树的遍历顺序,且 p i ≤ t i p_i\leq t_i piti。继续我们想到成立时,对于每一条边 u → v u\to v uv,必然满足 p u ≤ p v − 1 ≤ t v − 1 p_u\leq p_v-1\leq t_v-1 pupv1tv1。假如存在排列使树中此条件总成立,对其验证即可说明充分性(继续推理可发现,最终构造的不同排列总是等价的)。所以我们可以通过树上 dfs(或者可以算是 dp),求出 p u = min ⁡ v ∈ s u b u t v + d i s u v p_u=\min_{v\in sub_u}t_v+dis_{uv} pu=minvsubutv+disuv,然后离散再验证一下。

其实解释方法有很多,但是都不算很好想,建议读者自己动动脑。

最后看复杂度,显然为 O ( n log ⁡ 2 n ) \mathcal{O}(n\log^2n) O(nlog2n),细节需要卡一下常才可保证通过。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值