【题目描述】

初始状态的步数就算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;}