【题目描述】
初始状态的步数就算1
【输入格式】
第一个3*3的矩阵是原始状态;
第二个3*3的矩阵是目标状态。
【输出格式】
输出移动所用最少的步数。
【样例1输入】
2 8 3
1 6 4
7 0 5
1 2 3
8 0 4
7 6 5
【样例1输出】
6
【样例2输入】
2 8 3
1 6 4
7 0 5
0 1 2
3 4 5
8 7 6
【样例2输出】
18
上代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using
namespace
std;
const
int
fac[10]={1,1,2,6,24,120,720,5040,40320,362880};
const
int
dx[]={-1, 1, 0, 0};
const
int
dy[]={ 0, 0,-1, 1};
struct
node{
int
a[3][3],x0,y0;
int
step;
node():step(0){ }
};
node b,e;
queue<node> q;
bool
f[400000];
void
find0(node &x){
for
(
int
i=0;i<3;i++)
for
(
int
j=0;j<3;j++)
if
(x.a[i][j]==9){
x.x0 = i;
x.y0 = j;
return
;
}
}
void
init(){
for
(
int
i=0;i<3;i++)
for
(
int
j=0;j<3;j++){
cin>>b.a[i][j];
if
(b.a[i][j]==0) b.a[i][j]=9;
}
find0(b); b.step=1;
for
(
int
i=0;i<3;i++)
for
(
int
j=0;j<3;j++){
cin>>e.a[i][j];
if
(e.a[i][j]==0) e.a[i][j]=9;
}
find0(e);
memset
(f,0,
sizeof
(f));
}
int
cantor(
const
node &x){
int
t=0,d=0;
for
(
int
i=0;i<3;i++)
for
(
int
j=0;j<3;j++){
d = 0;
int
k,p;
for
(k=0;k<3;k++)
for
(p=0;p<3;p++)
if
(k*3+p>i*3+j && x.a[i][j]>x.a[k][p])
d++;
t += d*fac[8-(3*i+j)];
}
return
t+1;
}
bool
issame(
const
node &x,
const
node &y){
for
(
int
i=0;i<3;i++)
for
(
int
j=0;j<3;j++)
if
(x.a[i][j]!=y.a[i][j])
return
false
;
return
true
;
}
int
bfs(
const
node &b){
q.push(b);
f[cantor(b)] =
true
;
node u,v;
while
(!q.empty()){
u = q.front();
if
(issame(u,e)){
//(cantor(u)==cantor(e)){
return
u.step ;
}
q.pop();
for
(
int
i=0;i<4;i++){
v = u;
v.x0 += dx[i];
v.y0 += dy[i];
if
(v.x0<0 || v.x0>=3 || v.y0<0 || v.y0>=3)
continue
;
swap(v.a[v.x0][v.y0],v.a[u.x0][u.y0]);
if
(f[cantor(v)])
continue
;
v.step++;
q.push(v);
f[cantor(v)] =
true
;
}
}
return
-1;
}
int
main(){
init();
cout<<bfs(b)<<endl;
return
0;
}