一些题目(2)
奶牛选举
搜索
题意:在 5*5 的矩阵中找出规模为 7 的四连通块的个数。
初步解法:枚举第一个被取的格子是哪个。对于每个格子,若其上下左右四个格子已经有被取过的格子,就枚举其取或不取;否则不取当前格子。但是很明显是错的,因为在初始格子的周围添加一个后,能够取的格子就会变多,但是由于是顺序枚举,就会漏掉前面的可以取的格子。
正解:直接把上面的方法中「判断其四周是否有被取过的格子」这一步删掉。
更好的解法是把 7 拆成 4+3,也就是先深搜出一条长度为 4 的四连通块,注意是一条,也就是直接用深搜每次单方向扩展。然后在这个规模为 4 的连通块周围添加上 3 个格子即可。
约瑟夫问题
线段树
分析:我们知道约瑟夫问题的瓶颈在于找到下一个出圈的人的编号。如果用标记数组或链表,即使加了取模优化也仍然不够理想,依然是线性的复杂度。所以我们要用线段树来实现 O(logn) 的查找。
线段树一般用于统计,在这个问题中我们可以用线段树统计一个区间内的「剩余人数」。
那么,当我们要查找当前剩余的人中的第 k 个人时,就从根节点开始不断往下找。如果当前结点的左子树剩余人数大于等于 k,就在左子树中查找;否则在右子树中查找。找到一个人后删去,维护区间的剩余人数。
最舒适路线
枚举+并查集
题意:找出一条最大边与最小边比值最小的路径。
初步解法:枚举最大边是哪条,二分枚举最小边是哪条,用并查集判断连通性。
正解:先将边排序,枚举最小边是哪条,然后从最小边开始不断往图中依次加边,直到两点连通为止。这里运用了一点贪心的思想:确定了最小边之后,往后不断添加边直到两点连通,此时不必再加边,所以确定最小边之后,就已经确定了此时的最优解(如果有解的话),最大边就不用再枚举了,可以判断出此时最大边的最小值,即得到此时的最优情况。