帮助填字游戏填充算法

时间:2012-11-13 00:22:36

标签: algorithm crossword

这个问题在我的大学给了我,也许有人会有一个有趣的算法如何解决问题。 stackoverflow上有几个解决方案,但没有一个是好的(因为它们为所有可能性循环)。

问题:找到所有可能的组合,用于将给定的单词分配到给定的表格,网格(矩形,请参阅下面的输入)。应该没有空闲单元格,单词可以从左到右或从上到下。单词不能一个接一个地排在一行(列)。

输入:矩形区域,例如:

+-----+
|  *  | 
|     |
+-----+

+-----+
|   * |
|     |
|    *|
|   * |
+-----+

然后输入不同的单词(下一个输入数据)以填充该网格,例如:

cdi
zobxzst
tdxic
r
sc
zro
and etc ...

数字最初是未知的,但输入直到stdin结束 - 活动EOF。

输出:如果存在一个解决方案,则在填充网格中输出该可能的解决方案。 如果没有解决方案或解决方案的数量,则输出0或确切的数字。

示例:

(输入表格)

+-----+
|   * |
|     |
|    *|
|   * |
|  * *|
|  *  |
|     |
+-----+

然后是单词cdi zobxzst tdxic r sc zro rgfvacd oikf df x c r xvf ogish za sh fc hh h bfkh

(每个都作为输入,但在这里用空格分隔。)

输出(仅限1个解决方案):

+-----+
|zro*h|
|ogish|
|bfkh*|
|xvf*r|
|za*c*|
|sc*df|
|tdxic|
+-----+

重要提示:输入的网格仅受16(!)个单元格的限制,单词数量少于60个。我编写了一个搜索所有可能组合的算法,但由于执行时间有限,因此对我不起作用(我估计10秒)并且这个问题无法通过粗略算法解决(例如15个网格和大约60个!可能或更多可能的排列,可以在普通的2GHz PC上处理大约1天?)

也许存在另一种独特的解决方案。也许这个问题比编程更具数学性,或许可以使用一些左右组合与上下?或者加权细胞?

P.S。我有3个星期的时间来解决这个问题,如果没有,我可以在3周后在这里发布解决方案(好消息);)

2 个答案:

答案 0 :(得分:2)

  

在stackoverflow上有几个解决方案,但它们都没有问题(因为它们为所有可能性循环)。

我的想法可能也是错误的:但是这是我头脑中的一个想法。

  

我写了一个搜索所有可能组合的算法

如果有太多,那么问题可能是你也在搜索/循环不可能的组合以及可能的组合。

例如,当你在左上角放置一个像“zro”这样的单词时,很少有“可能”的组合可以放在它下面的垂直单词中:

  1. 第一个垂直单词必须以'z'
  2. 开头
  3. 第二个垂直单词必须以'r'
  4. 开头
  5. 第三个垂直单词必须以'o'
  6. 开头
  7. 第二行上的字母组合(由放置垂直字词产生)本身必须是有效字
  8. 因此:

    1. 选择任何单词并将其放在左上角
    2. 查找满足上述约束的现有单词
    3. 如果你找到一个或多个这样的词,那么继续这样看你是否可以解决整个事情;或者如果你失败了,那么再试一次使用不同的初始词
    4. 要点:

      • 不要生成每个完整的网格,然后测试它是否满足所有约束
      • 在构建网格时使用约束,以减少测试的可能性

      我建议您从最初的单词开始解决网格问题。

      不是测试左上角的每个单词,而是更好(例如因为它很快就消除了不可能性)生成起始位置[s]的方式是:

      • 找到最长的字词(例如rgfvacd
      • 查找所有可能的交叉/加入单词组合
      • 尝试将每个有效组合放在网格上

答案 1 :(得分:1)

我建议您首先应该看看您需要填写的单词长度,在您的示例中:

+-----+
|   * |
|     |
|    *|
|   * |
|  * *|
|  *  |
|     |
+-----+

你有两个7个字母的单词,三个1个字母单词等。

你应该根据计数对这个列表进行排序,然后首先尝试使用最低计数的wrod长度,在下一次迭代中你应该列出你需要找到的单词 - 例如三个以4个字母开头的单词'a' - 你应该计算你的单词列表中剩下的这些单词中有多少,然后选择其中单词最少的单词 - 如果它为0则返回。

希望它有意义。