【问题标题】:How to find the minimum number of moves?如何找到最小的移动次数?
【发布时间】:2019-05-09 09:34:44
【问题描述】:

注意:- 我已经通过回溯方法解决了上述问题,通过尝试所有不同的方式,我正在寻找一种非常有效的方式/模式。

我们得到一个大小为 'N' X 'N' 的棋盘。但它可以包含任意数量的白色方块和黑色方块,也可以任意顺序。

假设有'a'-白色方块和'b'-黑色方块,那么,

[a+b=n*n]

我们必须继续在棋盘上用黑色方块走棋,直到没有棋子为止。

这是在移动中发生的:-

1)我们在坐标:-(row,column) 处选择一个黑色方块并将其移动到 (row-1,column+1) ,仅当坐标为 (row-1,column+1) ) 还包含一个黑色方块。移动到新位置后,旧位置,即 [row,column] 变为空,即颜色变为白色。

2) 我们在 co-ordinate:-(row,column) 处选择一个黑色方块并将其移动到 (row-1,column-1) ,仅当坐标为 (row-1,column-1 ) 还包含一个黑色方块。移动到新位置后,旧位置,即 [row,column] 变为空,即它的颜色变为白色。

我们必须以最少的步数结束这个游戏,问题是找出这些步的顺序。

让我们用'1'表示黑色方块,用'0'表示白色方块......

例子:-

3X3 棋盘:-

0 1 0

1 0 1

0 0 0

以最少步数结束游戏的步数:-

1)将[1,0]处的黑色方块移动到[0,1]...现在棋盘看起来像这样:-

0 1 0

0 0 1

0 0 0

2) 我们将 [1,2] 处的黑色方块移动到 [0,1] 处,棋盘看起来像这样:-

0 1 0

0 0 0

0 0 0

现在,没有有效的移动,游戏结束:-)

给定一个大小为“N”x“N”的棋盘以及任何黑白格子的配置,如何找到以最少步数结束游戏的步数?

【问题讨论】:

  • 您似乎希望我们为您编写一些代码。虽然许多用户愿意为陷入困境的编码人员编写代码,但他们通常只有在发布者已经尝试自己解决问题时才会提供帮助。展示这项工作的一个好方法是包含您迄今为止编写的代码、示例输入(如果有的话)、预期输出以及您实际获得的输出(控制台输出、回溯等)。您提供的详细信息越多,您可能收到的答案就越多。检查FAQHow to Ask
  • 我不要代码,我只想知道解决方案背后的想法:-)

标签: chessboard.js


【解决方案1】:

查看此问题的一种方法是将其视为图形遍历。由于我们正在寻找 最短 移动,我们可以利用我们对图遍历算法的知识并考虑使用广度优先遍历。

我们将需要能够做几件事来实现这一目标:

  • 给定棋盘的某种配置,计算所有可以采取的合法棋步
  • 给定一个具有某种配置的棋盘和一个合法的走法,在应用该走法后计算棋盘的配置
  • 给定一个棋盘的某种配置,检查此配置是否为终端(这样就无法从该位置进行其他移动,游戏结束)。

现在我们有了这个,让我们看看如何将这个问题映射到图遍历问题。

  • 让初始配置成为图的 节点。
  • 从根节点引出的是我们可以从这个位置进行的合法移动。
  • 这些边指向的子节点是将边标签上的移动应用于父节点的配置。

那么寻找到终端位置的最短路径的过程将如下所示(从根节点开始):

  • 通过在给定此配置的情况下生成所有合法移动来扩展根节点的子节点。
  • 检查每个孩子,看看是否已达到终端配置。
  • 如果没有,请以呼吸优先的方式扩展子项(来自 BU 的 link 有更多关于这种遍历的实现细节的详细信息)

呼吸优先遍历的魔力在这里发挥作用。从这里我们重复这个扩展节点的过程,检查终端配置,如果我们没有找到这样的配置,则在图表中下降一个级别。

一旦我们找到终端配置,我们就知道从根节点(初始配置)到终端节点(游戏结束位置)的路径(代表移动的边)是最短的 .我们现在所做的就是计算返回根节点的边数,并且我们知道最小移动次数是多少。

【讨论】:

  • 注意:- 我已经通过回溯/图形方法解决了上述问题,通过尝试所有不同的方法,我正在寻找一种非常有效的方法/模式来解决 O 中的问题(n^2) 时间,其中 'n' 是棋盘的大小
猜你喜欢
  • 2022-08-24
  • 2020-07-04
  • 1970-01-01
  • 2014-04-21
  • 2016-07-03
  • 2014-10-13
  • 2019-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多