地址: http://codeup.cn/problem.php?cid=100000609&pid=2
思路:用BFS算法来完成。可以看成是走迷宫的改版
从第一矩阵变成第二矩阵,实际上可以看成 是0的位置移动
2 8 3 1 2 3
1 6 4 8 0 4
7 0 5 7 6 5
# # # # # # # 0 # 0 # # # # # # # #
# # # # 0 # # # # # # # 0 # # # 0 #
# 0 # # # # # # # # # # # # # # # #
从当前位置出发,把每一层的可能性都枚举出来,放入队列中,直到达到矩阵相等。
注意
1.期间0可能绕一个圈,又回到原位置。但是与此同时也有0正在朝正确的
道路前进,因此不是死循环。除非题目有问题。。。
2.Node.step = top.step +1 ; //注意是将上一层的步数相加,不是自增
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
int matrix[3][3],final[3][3];
int X[4] = {0,1,0,-1}; //数组增量,代表上下左右
int Y[4] = {1,0,-1,0};
struct node{
int x,y; //0的位置
int M[3][3]; //此时的矩阵
int last_x,last_y; //上一个状态时,0的位置
int step; //移动的步数
}Node;
bool judge(int x, int y){
if(x<0|| y<0|| x>=3|| y>=3) return false;
else
return true;
}
//判定是否与最终结果矩阵相同
bool same(int a[3][3]){
for(int i=0; i<3; i++){
for(int j=0; j<3; j++)
if( a[i][j] != final[i][j] )
return false;
}
return true;
}
int BFS(int x, int y){
queue<node> Q;
Node.x = x,Node.y = y; //将第一步的0的位置,步数储存
Node.step = 1;
for(int i=0; i<3;i++)
for(int j=0; j<3; j++)
Node.M[i][j] = matrix[i][j]; //第一步时,存好矩阵
Q.push(Node);
while(!Q.empty()){
node top = Q.front();
Q.pop();
for(int i=0;i<4;i++){
int newX = top.x + X[i];
int newY = top.y + Y[i];
//若不越界且移动后的位置不是原来的位置
if( judge(newX,newY) && (top.last_x !=newX || top.last_y !=newY ) ){
//则将 0 移动到新的位置
Node.x = newX;
Node.y = newY;
Node.last_x = top.x;
Node.last_y = top.y;
Node.step = top.step +1 ; //注意是将上一层的步数相加,不是自增
for(int i=0; i<3;i++)
for(int j=0; j<3; j++)
Node.M[i][j] = top.M[i][j];
swap(Node.M[newX][newY] , Node.M[top.x][top.y] );
if(same(Node.M)) return Node.step;
Q.push(Node);
}
}
}
return -1; //事实上不会发生错误...
}
int main(){
int x_0,y_0;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
scanf("%d" , &matrix[i][j]);
if(matrix[i][j] == 0){
x_0 = i;
y_0 = j;
}
}
}
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
scanf("%d" , &final[i][j]);
}
}
printf("%d" , BFS(x_0,y_0)) ;
return 0;
}