题目
描述
在一个3*3的九宫格棋盘里,放有8个数码,数码的数字分别是1~8。棋盘中还有一个位置是空着的,用0表示。可以通过在九宫格里平移数码来改变状态(即空格位在九宫格内能上下左右移动)。数码在任何情况下都不能离开棋盘。给出8个数码的初始状态(没放数码的空格用0表示)和目标状态,问从初始状态到目标状态,最少需要经过多少次移动操作。 例如 初始状态为:
2 6 4 1 3 7 0 5 8 \begin{matrix} 2 & 6 & 4 \\ 1 & 3 & 7\\ 0 & 5 & 8 \end{matrix} 210635478
目标状态为:
8 1 5 7 3 6 4 0 2 \begin{matrix} 8 & 1 & 5 \\ 7 & 3 & 6\\ 4 & 0 & 2 \end{matrix} 874130562
输入
两行 第一行9个数字,用空格隔开,表示初始状态 第二行9个数字,用空格隔开,表示目标状态
输出
一个数,即最短路径,如果没有答案,则输出-1
样例输入
2 6 4 1 3 7 0 5 8
8 1 5 7 3 6 4 0 2
样例输出
31
思路
此题要用康拓展开
康托展开
D_B解法(double_BFS)
显然,题目把初始状态和目标状态都告诉了你,典型的双B啊,注意一下空位的移动方式和移动之后的图的状态
代码
#include <cstdio>
#include <queue>
#include <iostream>
using namespace std;
struct node{
int step;
int a[12], area[4][4];
int flag;
int xx, yy, c;
}A, B;
queue<node>G;
int dx[4] = {
0, 0, 1, -1},
dy[4] = {
1, -1, 0, 0};
int v[2][362890], f[10] = {
1,1,2,6,24,120,720,5040,40320,362880};
inline int contor(int *A){
int sum = 0;
for(int i = 0; i < 9 ; i ++){
int x;
x = 0;
for(int j = i+1; j < 9; j ++){
if( A[j] < A[i] )
x++;
}
sum += f[8-i]*x;
}
return sum;
}
inline void Two_ways_BFS(){
while( !G.empty() ){
node t = G.front();
G