将每次的图从(1,1)开始到(3,3)的字符按顺序存进字符串以表示图,并存一下x的坐标,交换图中元素就swap一下字符串x对应下标和目标位置下标,对应下标计算方法为idx=3(i-1)+j-1(因为他存进字符串的顺序是他上面的行数乘3,再加上当前的列数,还要再减1是因为下标从0开始)
#include<bits/stdc++.h>
#define fast ios::sync_with_stdio(false); cin.tie(nullptr)
#define ft first
#define sd second
using namespace std;
const int MN=1e5+50;
typedef pair<int,int> pii;
char pic[5][5];
pii mv[4]={{0,1},{0,-1},{1,0},{-1,0}};
string tgt="12345678x"; //目标字符串
int ans=-1; //找到目标则更新答案,找不到,答案就是-1
struct s{ //结构体存每个状态的字符串,步数,x的坐标
string str="";
int stp=0;
int x=0,y=0;
};
inline void bfs(){
string ss;
int sx=0,sy=0;
for(int i=1;i<=3;i++){
for(int j=1;j<=3;j++) ss+=pic[i][j]; //生成初始图的字符串
}
for(int i=1;i<=3;i++){ //找一下初始图中x的坐标
for(int j=1;j<=3;j++){
if(pic[i][j]=='x'){
sx=i,sy=j;
break;
}
}
}
queue<s> q;
unordered_set<string> ust; //ust记录每个状态是否搜过,避免重复搜,当所有状态都搜过也没出目标,答案ans不会更新,就是-1
ust.insert(ss);
q.push({ss,0,sx,sy});
while(!q.empty()){
s t=q.front();
q.pop();
int id=-1;
if(t.str==tgt){
ans=t.stp;
return; //找到目标,直接退出
}
for(int i=0;i<4;i++){
int nx=t.x+mv[i].ft,ny =t.y+mv[i].sd;
if(nx>=1&&nx<=3&&ny>=1&&ny<=3){
string ts=t.str;
swap(ts[(t.x-1)*3+t.y-1],ts[(nx-1)*3+ny-1]); //字符x在字符串中对应下标为前面的行数乘3,加上列数,再减1(下标从0开始);
if(ust.find(ts)!=ust.end()) continue;
ust.insert(ts);
q.push({ts,t.stp+1,nx,ny});
}
}
}
return;
}
inline void solve(){
for(int i=1;i<=3;i++){
for(int j=1;j<=3;j=j){
cin >> pic[i][j];
if(pic[i][j]!=' '&& pic[i][j]!='\n') j++;
}
}
bfs();
cout << ans << '\n';
return;
}
int main(){
fast;
solve();
return 0;
}