这道题也太难了!但是看着书上敲下来,其实就是一个复杂版的BFS吧,比较新的是编码的部分。
#include <iostream>
#include <bits/stdc++.h>
#define maxn 1000000
using namespace std;
typedef int State[9];
State st[maxn],goal; //状态数组
int dist[maxn]; //距离数组
int vis[maxn],fact[9];
const int dx[] = {-1,0,1,0};
const int dy[] = {0,-1,0,1};
void init_lookup_table()
{
fact[0] = 1;
for(int i = 1;i<9;i++)
{
fact[i] = fact[i-1]*i; //阶乘
}
}
int try_to_insert(int s)
{
int code = 0;
for(int i = 0;i<9;i++)
{
int cnt = 0;
for(int j = i+1;j<9;j++) if(st[s][j]<st[s][i]) cnt++;
code+=fact[8-i]*cnt;
}
if(vis[code]) return 0;
return vis[code] = 1;
}
bool Bound(int x,int y)
{
return x>=0&&x<3&&y>=0&&y<3;
}
int bfs()
{
init_lookup_table();
int Front = 1,rear = 2;
while(Front<rear)
{
State& s = st[Front];
if(memcmp(goal,s,sizeof(s))==0) return Front;//找到了目标状态
int z;
for(z = 0;z<9;z++)
{
if(!s[z]) break;//找到了0的位置
}
int x = z/3,y = z%3;
for(int i = 0;i<4;i++)
{
int x1 = x+dx[i];
int y1 = y+dy[i];
int z1 = x1*3 + y1;
if(Bound(x1,y1))
{
State& t = st[rear];
memcpy(&t,&s,sizeof(s));
t[z1] = s[z];//新的0
t[z] = s[z1];//新的值
dist[rear] = dist[Front]+1;
if(try_to_insert(rear)) rear++;
}
}
Front++;
}
return 0;
}
int main()
{
for(int i = 0;i<9;i++) cin>>st[1][i];
for(int i = 0;i<9;i++) cin>>goal[i];
int ans = bfs();
if(ans) cout<<dist[ans]<<endl;
else cout<<-1<<endl;
return 0;
}
/**
2 6 4 1 3 7 0 5 8
8 1 5 7 3 6 4 0 2
**/