CountLightsOut
本题是 LightsOut 游戏的加强版。
在一个 6×6 的棋盘中,有些灯是开着的,有些灯是关着的(就像普通的 LightsOut 游戏那样)。
但是,你不知道哪些灯是开着的,哪些灯是关着的。每次你进行操作后,我只会告诉你「现在还有几盏灯亮着」。
你需要把所有灯都灭掉,才能通关。
这道题的过法很多,可以通过逻辑推演找试探解,也可以通过理论推导找解析解。从大家的做题效果上来说,如果找试探解的话,只要运气好,几分钟做完也没什么问题。但要找解析解就很麻烦了,光是写代码都得好一段时间。
不过,对于多周目玩家来说,寻找解析解则能一劳永逸地解决问题。找到稳定解法就不用再靠随机应变了,效率更高。
相比于朴素的 LightsOut 游戏而言,这关加强的点在于,玩家并不知道每盏灯的状态,只知道一个「总体情况」。那么如果能通过一定的技巧还原出每盏灯的状态,我们不就可以把它转换成朴素的 LightOut 了吗?至于朴素的 LightsOut 游戏,我们用不着自己解,上网找个 lightsout solver 就可以直接帮我们推导解题方法了。
试探解
绝大部分玩家初次做题时都会寻找试探解。一般来说大家有两种不同的策略:
一边分析灯的状态,一边灭灯,同步进行。
不急于灭灯,先把每盏灯的状态都分析出来。
两种策略都是可行的。在这里我就以第二种策略来介绍。
基本思路
首先,如果我们除了初始状态以外一无所知,那么在什么情况下我们可以笃定一盏灯的状态呢?
其实只有一种情况,那就是当点击这盏灯时,亮灯数的变化刚好和此格周围的的灯数相等。
就以下图为例,如果点击了左下角的位置,然后发现亮灯数从 $n$ 变成了 $n+3$,这说明什么?当然说明原来这三盏灯的状态都是「关」,而当我们点灯之后,三盏灯个状态都变成了「开」。

同样的道理,如果亮灯数从 $n$ 变成了 $n-3$,那就说明原来三盏灯都是开着的,点灯之后它们都关上了。
但是假如说,我们点灯之后发现 $n$ 变成了 $n+1$ 或者 $n-1$ 的话,那我们就没办法直接下判断了,因为只知道这个范围内「有几盏灯亮着」,却不知道「亮灯的都是哪些」。
假如说我们知道了一部分灯的状态,那么我们就可以据此进一步推导周围灯的状态。以下图为例,红色表示「已知是开着的灯」,黑色表示「已知是关着的灯」,那么当我们点击这个范围时,就可以根据亮灯数的变化,判断那个未知格的状态了。

如果从 $n$ 变成了 $n+3$,那就说明那个未知格原本是关灯状态;如果从 $n$ 变成了 $n+1$,那就说明那个未知格原本是开灯状态。
按照这个思路,我们就可以一步步通过已知信息推导出未知信息。
解析解
用 $6\times6$ 的格子解释起来还是太麻烦了点,我先用 $3\times2$ 的情况来作说明吧。
第一步

如图所示,我们给每个格子一个布尔值,用 $1$ 表示灯开着,$0$ 表示灯关着。
而我们又知道,经过一次点击行为后,亮灯数的变化预示着「受影响范围内有多少盏灯原本是亮着的」。
举个例子,如果我们点击了左下角的位置,那么 $b_1,,b_2,,b_4$ 会受到影响,变成它的非值;而亮灯数从 $n$ 变成了 $n-1$,这就说明在 $b_1,,b_2,,b_4$ 三盏灯中,有两盏原本是亮着的:
列出这个式子之后,记得再点一下左下角,恢复原始状态。
接下来我们如法炮制,还可以再点击 $b_2$ 所在格,列出如下方程($c_n$ 自行推算):
同理,还有四个方程可列:
Last updated
