八数码问题也称为九宫问题。在3×3的棋盘上摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。棋盘上还有一个空格,与空格相邻的棋子可以移到空格中。给出一个初始状态和一个目标状态,求出从初始状态转变成目标状态的移动棋子步数的最少值。
一般的目标状态是指下面这样的排列方式。
我们先讲解下面这几个子问题,从而一步一步解决它。
1.康托展开和逆康托展开
假设有A,B,C,D四个字母的一个排列D,B,A,C,现在要求这个排列是字典序中的第几个。康托展开的公式是X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0!, 其中,ai为当前未出现的元素中是排在第几个(从0开始)。在这个例子中,X=a4*3!+a3*2!+a2*1!+a1*0!。
a4=D这个元素在子数组D,B,A,C中是第几大的元素。A是第0大的元素,B是第1大的元素,C是第2大的元素,D是第3大的元素,所以a4=3。
a3=B这个元素在子数组B,A,C中是第几大的元素。A是第0大的元素,B是第1大的元素,C是第2大的元素,所以a3=1。
a2=A这个元素在子数组A,C中是第几大的元素。A是第0大的元素,C是第1大的元素,所以a2=0。
a1=C这个元素在子数组C中是第几大的元素。因为子数组只有1个元素,所以a1=0。
所以,X=3*3!+1*2!+0*1!+0*0!=20。
如果已知某个排列是字典序中的第20个,求出这个排列的过程就是逆康托展开。