我在这里试图寻求有关算法的帮助。
我有一个7x7的整数网格,它遵循两个规则集: 第一个规则集(我已经成功编程)状态:
数字(1)将随机放置在内部5x5网格中。使用(1)的位置,填充内部5x5网格的其余部分,以使相邻的数字相邻(垂直,水平或对角线)。
这部分我已经完成,我有一个程序可以根据(1)的位置填充内部5x5网格,同时避免将自身锁定在其他网格点之外。这是我的程序生成的内部5x5网格的示例(为清楚起见,外部正方形标记为“ o”):
o|o |o |o |o |o |o
o|8 |9 |10|14|15|o
o|7 |11|13|17|16|o
o|6 |12|18|20|21|o
o|1 |5 |19|22|23|o
o|2 |3 |4 |24|25|o
o|o |o |o |o |o |o
第二个规则集指出: 然后,必须使用数字2-25填充7x7网格的外部正方形,以使内部网格内的任何数字Y都位于与行,列或对角线相同的行,列或对角线内(仅在穿过中心的“ X”中为对角线)外圈中的Y。
我在这里发贴是不得已的。我花了大约20个小时来研究第二个规则集,并尝试了几次解决方案(最多只能在外圈中留出4个空白空间),感觉就像在撞砖墙。有没有我没有看到的算法?朝着正确方向的任何一点都将不胜感激。
答案 0 :(得分:0)
免责声明:以下内容不是很优雅。我之所以建议这样做,是因为它非常容易实现,并且,如果您花了20个小时没有取得进展,那么我猜您不会对挑剔的解决方案那么挑剔。 :-P
除了1
之外,第二个规则集实际上完全不依赖于数字的值;就17
而言,它只是一个无意义的标签,需要复制。
因此,为了避免分心,您可以将示例网格视为:
o|o|o|o|o|o|o
o|A|B|C|D|E|o
o|F|G|H|I|J|o
o|K|L|M|N|O|o
o|1|Q|R|S|T|o
o|U|V|W|X|Y|o
o|o|o|o|o|o|o
您的目标是按照第二个规则集指定的方式通过A
(Y
除外)复制1
。
此外,第二个规则集非常对称。如果您编写一个flip_horizontal
函数,一个flip_vertical
函数和一个transpose
函数,那么1
可能实际上只有六个不同的位置:
o|o|o|o|o|o|o
o| | | | | |o
o| | | | | |o
o|1|1|1| | |o
o|1|1| | | |o
o|1| | | | |o
o|o|o|o|o|o|o
所以,您可以做的是:
手动解决六个可能的不同情况中的每一个,作为一个人,这并不难。例如,上面的示例:
o|o|o|o|o|o|o
o|A|B|C|D|E|o
o|F|G|H|I|J|o
o|K|L|M|N|O|o
o|1|Q|R|S|T|o
o|U|V|W|X|Y|o
o|o|o|o|o|o|o
具有此解决方案:
A|F|G|C|N|J|E
B|A|B|C|D|E|D
H|F|G|H|I|J|I
L|K|L|M|N|O|O
Q|1|Q|R|S|T|R
U|U|V|W|X|Y|X
M|K|V|W|S|T|Y
(我建议在文本编辑器中执行此操作,并在输入时将字母空白,以便您可以轻松地看到剩下要做的事情。您不必对此进行非常系统的猜测和检查,再加上遇到问题时进行调整就足够了。为此,您可以使用以上示例作为其他至少一些情况的起点。)
对于这六个案例中的每个案例,编写一个处理该案例的函数。这些函数中的每一个实际上只能是二十四行,例如array[4][0] = array[3][2];
。这并不令人兴奋,但可以使用。
编写一个函数来检查1
是否在可接受的位置。如果是这样,它将从步骤#2调用适当的函数;否则,将调用该函数。如果没有,它将调用适当的flip
函数,然后递归调用自身,然后再次调用相同的flip
函数以恢复原始位置。
编写一个测试程序,对1
的所有25个可能位置执行全部算法(两个规则集),并验证结果是否始终满足两个规则集。 (这很重要,因为测试总是很重要,更具体地说,是因为在步骤2中很容易错过错字。)