Atcoder AGC004 解题报告
\(A.\ Divide\ a\ Cuboid\)
简要题意:
用若干个\(1 \times 1 \times\)的小方块(立方体)组成一个\(A \times B \times C\)的大长方体,每个小方块可以涂成红色或蓝色,但要满足以下要求:
- 至少有\(1\)个红色方块与\(2\)个蓝色方块。
- 所有的红色方块必须组成一个长方体。
- 所有的蓝色方块必须组成一个长方体。
求所有满足要求的染色方案中,红色方块数与蓝色方块数相差个数的最小值。
题目解法:
如果有偶数答案就为\(0\),如果没有那么就砍最长的边。
\(B.\ Colorful\ Slimes\)
简要题意:
现在有一群史莱姆,它们有\(N\)种颜色。
现在你需要搜集齐\(N\)种颜色,但是只能够使用下面的方法:
- 选择颜色\(i\),然后花费\(a[i]\)的代价抓一只颜色为\(i\)的史莱姆。
- 施展魔法,让已经抓到的所有的史莱姆的颜色都从\(i\)变为\(i+1\),代价是\(x\)(颜色为\(N\)的史莱姆的颜色变为1)。
现在要求你以最小的代价搜集齐\(N\)种颜色,输出最小代价。
题目解法:
考虑枚举用了几次魔法(实现的时候是最多多少次,因为浪费了肯定不优,所以没事),假设是\(M\)次。
那么我们处理出每一个点向前的\(M\)步中的代价最小值,让这只史莱姆在那个位置抓,就好了。
这样一定是没有问题的,显然可以构造。
\(C.\ AND\ Grid\)
简要题意:
给定一个网格图,有些位置已经被涂色。
要求构造两个相同大小的网格图,并且在上面涂色,需要保证颜色四联通。
满足这两个网格的涂色部分的重合位置恰好是给定的网格图的涂色位置。
题目保证边界上不会被涂色。即对于第一行、第一列、第\(H\)行、第\(W\)列,都不会有#出现。
题目解法:
发现题目保证边界没有染色,这是一个很好的条件,考虑在这上面做手脚。
我们考虑用两个对称的梳子来构造。
就是第一个图的最左边全染了,最右边不染,中间的奇数行染,第二个图是其取反。
这么做之后,发现这两个图的\(And\)是一个空的棋盘,而且两个图再在任意一个空位置染色都是联通的。
那么我们就将原图中染色的点在两个图中都染上,就做完了。
\(D.\ Teleporter\)
简要题意:
有\(N\)个城市,每个城市有一个传送点,都可以传送到唯一的另外一个城市。
保证从任何位置出发经过若干次传送之后能够到达\(1\)号城市。
现在希望修改一些点的目的地,使得从任何一点出发在传送\(K\)次之后恰好都能到达\(1\)号城市,求最少要改变目的地的城市的数量。
题目解法:
注意到是恰好\(K\)次到\(1\)号点,而且原图是一个基环内向树,\(1\)号点在环上。
那么如果环上还有其它点,一定只能有一个点达到要求,所以第一步就是将\(1\)号点连成自环。
之后就是一棵指向父亲的树了,而且条件就变成了每一个点,最多\(k\)步到达根。
这个可以考虑类似树形\(DP\)的"树形贪心",就是一个子树不得不改,才改。
我们从叶子向上考虑,如果一个点,子树中到它的最远距离有\(K-1\)了,那么它就要连到根上,因为如果不连,最远的点就不满足要求了。
考虑实现,如果一个点的父亲变成根了,那么回溯的时候这个子树就没有距离的贡献了,之后就做完了。
\(E.\ Salvage\ Robots\)
简要题意:
有一个棋盘,上面要么是空的,要么有一个机器人,要么是一个出口(有很多机器人,但只有一个出口)。
每次可以命令所有机器人向上下左右中的某个方向移动一格,如果它超出了棋盘的边界就会消失。
如果它到了出口的位置就会被你救下(并且从棋盘上消失)。求你能够救下的机器人的最大值。
题目解法:
因为只有一个出口,我们可以认为机器人不移动,利用运动的相对性,看成是出口在动。
显然初始的时候,如果一个机器人也不杀死,那么出口能够活动的范围是一个矩形,在这个矩形内的机器人都能被吸收。
那么我们考虑当出口的活动范围是\((L,R)和(U,D)\)这一个矩形的时候的答案。
这个可以设\(f[L][R][U][D]\)表示这个矩形的答案,每次可以拓展一个方向转移,注意用前缀和优化以及转移的时候要判断一些细节。
\(F.\ Namori\)
简要题意:
给定一个\(N\)个点,\(M\)\((N-1 \le M \le N)\)条边的图,没有自环,没有重边。
每个点初始是白色。每次操作可以处理一条边,其两个点如果颜色相同则都变成相反的颜色(黑变白,白变黑)。
询问能否将每个点都变为黑色。如果能,输出最少的操作数;如果不能,输出-1.
题目解法:
这里\(M=N-1\)有挺多的部分分,而且我也只会这个部分分\(QAQ\)。
我们考虑给每一个点安排一个权值,其中奇数层的权值是\(1\),偶数层的是\(-1\)。
如果一个点是白色,那么这个点看上去的数值就是它的权值。
如果一个点是黑色,那么这个点看上去的数值就是它的权值的相反数。
那么题目的操作就是每次将一个数值\(1\)从选的两个点中的一个点移动到另一个点。
最终的目标就是所有的\(1\)都在偶数层的点,所有的\(-1\)都在奇数层的点。
我们考虑对于每一条边计算贡献,显然,一条边要交换的次数,就是子树中\(1\)和\(-1\)的个数的差值。
这是因为只有那么多是一定要和子树外的点交换的,而且那些可以内部匹配的点一定不会走父亲这条边交换。
那么我们就做一个简单的树形\(DP\)就完事了。