LOJ #3831. 「IOI2022」囚徒挑战 题解
Description
一个监狱里关着 名囚徒。 有一天,监狱长给了他们一个重获自由的机会。 他把装钱的两个袋子 A 和 B 放在一个房间里。 每个袋子装有若干枚硬币,数量的范围在 到 之间(包含 和 )。 两个袋子里硬币的数量不同。 监狱长给囚徒们提出了挑战,目标是指出硬币数量较少的那个袋子。
房间里除了袋子还有一块白板。 任意时刻白板上写着一个数,一开始写的是 0。
监狱长让囚徒一个接一个地进入房间。 每个进入房间的囚徒不知道他之前进入过房间的囚徒有多少人,也不知道是哪些人。 每次一个囚徒进入房间时,他看一眼白板上目前写的这个数。 看完之后,他必须在袋子 A 和 B 之间做出选择。 接着,他检查自己选的那个袋子,知道了里面有多少枚硬币。 然后,这名囚徒必须选择做以下两种行动之一:
- 将白板上的数改写成一个非负整数,并离开房间。 注意他可以改变成新的数,也可以保留当前的数。 然后挑战继续进行(除非所有 名囚徒都已经进过房间)。
- 指出硬币数量较少的那个袋子。这会立即结束挑战。
对于已经进过房间的囚徒,监狱长不会让他再次进入房间。
如果某个囚徒正确地指出硬币较少的袋子,则囚徒们获得挑战的胜利。 如果指出的袋子不正确,或者所有 人进过房间之后还没有人尝试指出硬币较少的袋子,则囚徒们失败。
挑战开始之前,囚徒们集合在监狱大厅商量应对挑战的共同策略,分以下三个步骤:
- 他们挑选一个非负整数 ,作为他们可能会写在白板上的最大的数。
- 他们决定对任意一个数 ,如果某个囚徒进入房间后看到白板上写着数 ,那么他应该去检查哪个袋子。
- 他们决定当某个囚徒得知选中的袋子里的硬币数量后要采取的行动。具体来说,对任意写在白板上的数 和检查选中的袋子里的硬币数量 ,他们要决定做出以下两种行动之一:
- 白板上应该要写一个 到 之间(包含 和 )的什么数;
- 指出哪个袋子是硬币较少的。
如果赢得挑战,监狱长会在囚徒们继续服刑 天后释放他们。
。
Solution
首先这题有个很简单的想法是按照 进制从高位到低位进行比较,并且把上一位的值压在状态里。即从高位到低位的第 位,如果当前数是 ,则为 ,否则为 。然后对于这两种状态去询问与它们之前询问的数不同的那个,即可得到另一个数的值,如果能在第 位比较出来,则直接结束。否则递归到第 位,同时每次询问的数交替即可。
这么做是 次,不太能过。改成 进制可以变成 次。
考虑优化。由于最后一定能比出大小,所以递归到最低位时,如果当前位为 或者 ,则可以直接返回。于是就变成 次了。
上面的做法已经不好优化了,考虑将 进制改成类似线段树的结构,即我们可以确定当前数在 的范围内,然后询问另一个数,如果能比出大小就结束,否则将 平均分成 份进行处理,显然这是和原先的做法等价的。
这个做法和上面的小优化容易结合起来,即如果询问出来的数为 或者 就能结束,也就是区间长度 变为 ,经过计算次数变为 次。
最后的优化就是注意到区间长度不超过 时进行三分是很浪费的,因为划分后长度为 还是 是一样的,所以这个时候二分是一样的,总次数就变为 次了。
Code
1 | |