计蒜客杂题记录

本题解只记录思想。若读者觉得题解思路清晰且想看看代码,可私信联系。

整理:

目录:

基础数据结构
练习题:括号匹配(栈)

读取字符串,读到左括号,将其推入栈。读到右括号,栈顶推出一位。如果不能推出,或者栈中最后还剩元素,说明不合法。

练习题:网页跳转(双栈模拟)

访问一个页面,将其加入其中第一个栈中,同时另外一个栈全部清空(无前进的页面)。
返回一个页面,如果第一个栈的大小大于一(前面有访问过网页),那么将原页面置于另外一个栈中,访问栈顶。
前进一个页面,将第二个栈的栈顶置于第一个栈中,然后访问栈顶。
栈体现的思想是后入先出,所以题目的要求也是符合这种模型的。

练习题:n个最小和(优先队列)

先将 { ( A i + B 1 ) ∣ i ∈ [ 1 − n ] } \{(A_i+B_1)|i∈[1-n]\} {(Ai+B1)i[1n]}置于优先队列中,后每取出一个数,将 ( A i , B k + 1 ) (A_i,B_{k+1}) (Ai,Bk+1)置于优先队列中,进行n次便可。
优先队列体现的思想是优先级高的先出,组合求最小的前n个可以考虑优先队列。重载运算符的时候,要记得权值的比较是反过来的(一半重载<)

练习题:朋友(带权并查集)

用带权并查集维护一下即可。带权并查集可以用来维护一些节点与根节点有关系的树,比如说集合的大小(例如这道题),或者节点到根节点的距离(下面的题目)。关于带权并查集的模板,在计蒜客上有。

队列合并(带权并查集)
在排队过程中,初始时,一人一列。一共有如下两种操作:
合并:令其中的两个队列A,B合并,也就是将队列A排在队列B的后面
查询:询问某个人在其所在队列中排在第几位。

前面一道题说了,使用带权并查集即可。

练习题:找出所有谎言(有意思的权值并查集)

剪刀石头布原则蕴含一个博弈环,实际上我们只需要拿一个点去跟其他点作比较,判断输赢平三种情况即可(确认该点与其他点的输赢关系,其他点的相互关系也能确定下来)。默认该点(下文称根点)的博弈值为0,某节点相对根点为赢,输与平分别为1,2,0,将其加入权值并查集中。当两个节点对应的根点不同时,以两结点关系来连接两个对应根点。两个节点对应根点相同时,判断情况是否矛盾,以此来判断真假。
(权值并查集在重的是节点与根点的关系,与其他节点并无关系。节点合并的时候也是之前权值加上父节点(原先根点)更新后的权值,这个节点就只与新根点有关了)

未整理:

正方形(剪枝dfs)

啊啊啊啊啊啊啊啊啊我tm居然做了一晚上debug对于正n边形木棍匹配的题目,改用先将一条边选出的搜索方式,仔细思考一下,这样的回溯搜索深度很低,完全可以接受。当n-1的合法边被选完后,最后一边也合法,直接跳出。

习题:逃跑(有时间维度的bfs)

这道题涉及到了时间维度,对于这类搜索,最好加一个维度,记为 v i s [ t ] [ x ] [ y ] vis[t][x][y] vis[t][x][y],表示在在t时刻是否能访问这个(x,y)点。在这道题中用此来bfs会方便许多(因为可以预处理子弹的到达情况)。处理的时候比较麻烦,建议用d来划分上界,以免超时。预处理的时候注意多颗子弹在预定时间内打出的轨迹的描述方法(我用的是二重循环,大抵标程也是如此)。

习题:墙壁涂色(思维递推)

考虑 a n s [ n ] , a n s [ n − 1 ] , a n s [ n − 2 ] ans[n],ans[n-1],ans[n-2] ans[n],ans[n1],ans[n2]的关系。
当第 n n n个填充块颜色与两侧不同时,因为颜色只有三种可选择,所以只有一个颜色可以选。忽略第 n n n个色块,这个排列是合法的 f ( n − 1 ) f(n-1) f(n1),所以方案加 f ( n − 1 ) ∗ 1 f(n-1)*1 f(n1)1
当第n个填充块与两侧相同时,有两种颜色的选择方案,但忽略第n个填充块,这个排列是不合法的。那么就相当于在前n-2种方案中添加两个色块,其中一个色块的颜色跟我们第n个色块相邻的颜色相同,构成我们的方案二。答案便是 f ( n ) = f ( n − 1 ) + f ( n − 2 ) ∗ 2 f(n)=f(n-1)+f(n-2)*2 f(n)=f(n1)+f(n2)2,递推公式有几项,边界值就写几项。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值