前言
八数码这个数一数二的入门题目,想必大家都会了。
八数码题目描述
输入源八数码形状,输出移到目标形状所需步数。
以前以为八数码拓展就是用IDA*、双向广搜等高大上的搜索来做。
然而,有更高级的八数码问题。
引入
我们看到这样的一道题:
jzoj100030. 【NOIP2017提高A组模拟7.8】为了爱情
题意是:
给你多个n*n的八数码矩阵(n为奇数且小于100),要求判断这个八数码矩阵能否还原为原来的样子
例:
123
456
078
可以还原为
123
456
780
至此,我们发现,这题直接暴力是很难搞的,加优化也无济于事。
能否转移模型呢?
正题
首先,我们考虑3 * 3的情况。
先把原序列变成一个3 * 3的一维序列:123456780这样的形式。
我们发现,如果把0向左边或向右边移动一格时,我们发现,原序列的逆序对的个数不变。
但是,把0向上或向下移动一格时,就相当于把交换的数字在序列中向前或向后交换2次。
所以,每次交换对于逆序对来说,只用2种情况——
1、当交换的两个数都比之大或小,则逆序对个数加2或减2
2、当交换的两个数一个比之大,一个比之小,则逆序对个数不变。
那么再这种情况下,无论如何,逆序对的奇偶性就是不变的。
而逆序对的大小可以无限调动。
那么就可以发现,只要初始的序列的逆序对奇偶性与结束的序列的逆序对的奇偶性相等,那么一定可以达到目标。
如果真的不明白,这里有一些奇妙的证明方法,我贴出来看——
(假设是还原到123456780的序列)
首先,1,2归位很容易。
但是3有点困难。
先这样摆好。
再这样把0调一下。
交换0,3,依次归位即可。
接下来考虑4和7怎么弄,显然,4很好归位,但是7呢?
其实可以和3类似地弄。
bingo!成功还原外面的一层数字。
那么至于中间的那4位,随意排列组合,发现只有逆序对为偶数时才可以还原到123456780的序列。
至此,就证明完毕了。
当然,如果不是还原到123456780而是别的什么序列,
我们可以把其实序列与结束序列都往123456780这个序列还原。
最后也是中间那4位之间的交替,所以,可以以奇偶性来判断。这叫殊途同归,数学老师说的
其次,我们可以拓展到n * n(n为奇数)的情况
同上,我们可以依照一样的方法来构造逆序对,然后判断奇偶性。
每次上下移动0,就会交换偶数个格子,然后同理的,奇偶性不会变。
同样的我们可以用那种还原最外围的方法一层一层还原,最后也是只剩4个数字。
那么,这种情况也是很好弄地。
判断方式——
若原序列的逆序对的奇偶性与目标序列的逆序对的奇偶性相等,则可以到达。
最后,我们可以再拓展到n * n(n为偶数)的情况
这种情况下,由于每次上下移动0,会交换奇数个格子。
那么这种情况,我们可以发现,每次上下移动0时都会使得逆序对的奇偶性改变。
所以说,我们若是要把0移到目标状态下的那个0的那一行上,就会改变奇偶性x次。
(设x表示0向下移动x次到达目标状态下的0的那一行)
这样,我们就可以多加一次判断即可——
若原序列的逆序对的奇偶性与目标序列的逆序对的奇偶性相等,且x为偶数,则可以到达。
或
若原序列的逆序对的奇偶性与目标序列的逆序对的奇偶性不相等,且x为奇数,则可以到达。
至于证明,我也是同上面地去弄出最外围的几行,最后4个格子也是与x和逆序对有关,判断即可。
于是乎,上面那道题就可以完美解决了。
利用树状数组搞逆序对数,再去判断奇偶性即可。
有没有更多的拓展呢?
继续拓展到n * n * n的情况
我同样地弄出个序列,
那么每次0朝3个方向可以走。
第一个方向不影响逆序对的奇偶性。
第二个方向相当于交换了次。
第三个方向相当于交换了次。
所以,我们可以考虑继续分类讨论。
- 当n为奇数时,每次0移动都是交换偶数次,不影响奇偶性,判断同上。
- 当n为偶数时,每次0移动时,第二个方向与第三个方向都相对应地交换了奇数次。
- 那么,我们可以设x为0到目标状态的0的二维平面的距离(删去第一个方向)。
- 所以判断也是和上面一样的。
至此,分类讨论结束了。
思考题:怎么弄?
题外话
当然,可以拓展到非常多维的状态,但是,应该没人喜欢搞这么多东西的吧。
其实,这个东东不常用,只是当做一种长知识的东西吧,锻炼思维。
来源:https://www.cnblogs.com/RainbowCrown/p/11148373.html