数字链接游戏
游戏:考虑一个 n × n 方阵。有的方格是空的,有的方格是实心的,还有一些非实心方格用整数 1, 2, 3, ... 每个整数在棋盘上正好占据两个不同的方格。玩家的任务是通过仅使用水平和垂直移动的简单路径连接棋盘上每个整数的两次出现。不允许两条不同的路径相互交叉。任何路径都不能包含任何实心方块(任何路径上都禁止出现实心方块)。最后,所有非实心方块必须由路径填充。
算法:为了准备一个给定棋盘大小 n × n 的有效随机谜题,我们首先在棋盘上生成随机简单的相互不相交的路径。如果在所有生成的路径之外仍有一些孤立的方块,则将这些孤立的方块标记为实心(禁止)。然后我们提供路径的端点和实心方块的列表作为拼图。
因此,我们首先生成一个解决方案,然后从解决方案中解决难题。路径和实心方块将 n × n 板隔开。我们使用 union-find 数据结构来生成这个分区。数据结构处理棋盘上 n^2 个方格的子集。
伪代码:
- 在棋盘上随机定位正方形 (i, j) 和 (k, l),使得:
(a) (i, j) 和 (k, l) 是彼此的邻居,并且
(b) (i, j) 和 (k, l) 都不属于到目前为止生成的任何路径。如果在整个棋盘上都没有找到这样的一对方格,则返回 FAILURE /* 这里,(i, j) 和 (k, l) 是要构建的新路径上的前两个方格。 */ - 将包含 (i, j) 和 (k, l) 的两个并集树合并。
- 只要可以扩展当前路径,就重复:
重命名 (i, j) = (k, l)。
找到 (i, j) 的随机相邻正方形 (k, l),使得:
(a) (k, l) 不属于目前生成的任何路径(包括当前路径)
(b) 在部分构建的当前路径上唯一的邻居 (k, l) 是 (i, j)。 - 如果找不到这样的邻居(k,l),则路径无法进一步扩展,因此中断循环
- 否则,将 (i, j) 和 (k, l) 所属的两棵并集树合并。
- 设置位于新路径开头和结尾的两个方块的端点标志。
- 返回成功
完整的文章运行代码。