在2D矩阵中找不到爆炸性地雷的可能形成,其中一些单元格包含与它们相邻的偶数/奇数地雷的信息

问题描述 投票:1回答:3

我正在尝试制作涉及2D网格的游戏,其中给出一些提示,玩家可以避免包含爆炸性地雷的细胞。我遇到了一个特殊的情况,给出了一些提示,我想知道有多少种地雷是可能的。

让我们有一个2D矩阵。每个单元可能是空的或可能包含爆炸性矿井。每个单元格都有一些信息。如果单元格的值是

  • 'E':这意味着即使没有与该单元相邻的单元也包含地雷。
  • 'O':这意味着与该单元相邻的单元中的奇数没有包含地雷。
  • 'N':表示没有'E'或'O'的值。它没有说明它的周围和它自身。

下面给出的2d矩阵的示例: N N. N N. 并非所有可能的阵型都是16。 上 上 哦.E 并非所有可能的阵型都是4。

这些是我手工计算的值。我坚持制作一个有效的程序,用于计算网格尺寸的所有可能形式

algorithm matrix data-structures dynamic-programming puzzle
3个回答
2
投票

基本上你必须在Z / 2上求解方程组。它实际上非常类似于玩一款名为Lights Out的游戏。我们以此板为例。

O N
O N
O E

让我们为不同的董事会职位制作变量。

x11 x12
x21 x22
x31 x32

我们得到这样的方程式。每个qazxsw poi变成像qazxsw poi这样的等式。每个qazxsw poi变成像O这样的等式。

(sum of neighbor variables) = 1 (mod 2)

使用Z / 2上的高斯消元法将这些方程式放在E中。 Z / 2很有趣,因为加法和减法之间没有区别。简而言之,我们重复选择一个出现在某个等式中的变量,将该等式添加到包含该变量的每个其他等式中,并将该等式设置为一边。我会证明。

(sum of neighbor variables) = 0 (mod 2)

为了让事情变得有趣,让我们选择x12 + x21 = 1 (mod 2) x11 + x22 + x31 = 1 (mod 2) x21 + x32 = 1 (mod 2) x22 + x31 = 0 (mod 2) 中的row echelon form

x12 + x21 = 1
x11 + x22 + x31 = 1
x21 + x32 = 1
x22 + x31 = 0
----

请注意,x21x12 + x21 = 1都简化为x11 + x22 + x31 = 1 (x21 + x32) + (x12 + x21) = (1 + 1) ==> x12 + x32 = 0 x22 + x31 = 0 ---- x12 + x21 = 1 ,因为我们正在使用x21 + x21。我们现在选择1 + 1中的0

mod 2

我们没有预留的方程式中的所有变量都是不同的,因此接下来的两个步骤很无聊。

x22

我们有x11 + x22 + x31 = 1独立方程,所以答案是x12 + x32 = 0 (x22 + x31) + (x11 + x22 + x31) = (0 + 1) ==> x11 = 1 ---- x12 + x21 = 1 x11 + x22 + x31 = 1 解决方案(一般来说,---- x12 + x21 = 1 x11 + x22 + x31 = 1 x12 + x32 = 0 x11 = 1 )。一种无聊的结果,但它就是这样。

当我们减少方程时,会发生两件有趣的事情。让我们考虑以下板块。

4

我们得到以下方程式。

2^(3*2 - 4) = 4

现在,让我们减少。

2^(board squares - equations)

我们最终得到两个退化方程E E E E 。这意味着我们给出了冗余信息,并且它们不算作独立方程。这里的答案是x12 + x21 = 1 x11 + x22 = 1 x11 + x22 = 1 x12 + x21 = 1

可能发生的另一件事是我们得到一个方程x12 + x21 = 1 x11 + x22 = 1 x11 + x22 = 1 x12 + x21 = 1 ---- x11 + x22 = 1 x11 + x22 = 1 (x12 + x21) + (x12 + x21) = (1 + 1) ==> 0 = 0 ---- x12 + x21 = 1 (x11 + x22) + (x11 + x22) = (1 + 1) ==> 0 = 0 0 = 0 ---- x12 + x21 = 1 x11 + x22 = 1 。在这种情况下,没有与提示一致的解决方案。


1
投票

事实证明,这对于暴力来说不应该太糟糕,至少如果你的电路板不是太大。

您可以定义一组炸弹,其中每个单元格可以是0 = 02^(2*2 - 2) = 40 = 1,其中Present表示那里可能有也可能没有炸弹。然后,您可以编写一个方法来接收您的电路板和这组炸弹,并确定电路板是否绝对无效,或者可能有效,具体取决于任何Not Present电池的实际值。

然后你开始走板。将第一个单元格设置为Unexplored,并查看是否会导致可能有效(或绝对无效)的板。如果它可能有效,请将recurse设置为下一个单元格。然后将第一个单元格设置为Unexplored,看看它是否有效,如果它是递归到下一个单元格。

对于具有小面积无效的板的修剪应该与完全强力的暴力相比显着地削减搜索空间。

当您检查电路板是否有效时,您可以通过仅检查更改的单元格周围的方框中的单元格进行优化,因为这些是唯一可能受影响的单元格。

这不是全动态的动态编程,并且可能会受益于一些记忆:如果右下方的炸弹组合无效(右下角是探索的最后一个区域),它会一次又一次地尝试它们在其他地方使用不同(有效)的炸弹组合。

如果你的董事会有一个很大的开放区域,这也将陷入困境,因为会有大量的组合,这将仔细探索每一个。

我把一些C#扔在一起来说明我的想法。这不是很整洁或特别清楚(为此我道歉 - 我没时间整理它),但它找到了你的第二个例子的4个解决方案。

这是使用递归编写的,因此将使用更大的板吹制堆栈。重写它是迭代的。

Unexplored

1
投票

可爱的问题。听起来像编程竞赛风格的问题。暗示:

将其表示为GF(2)上的线性代数问题(即,使用算术模2),然后使用高斯消元法。

暗示:

如果我们给出矩阵A和向量b,你能算出等式$ Ax = b $的解的个数吗?怎么样?

© www.soinside.com 2019 - 2024. All rights reserved.