AcWing 845. 八数码
原题链接
中等
作者:
满目星河_0
,
2021-03-31 12:32:56
,
所有人可见
,
阅读 236
带注释(超详细)
//算法思想:利用一个字符串来存储每种状态,用一个哈希表来存放每种状态到起始状态的步数。
//用一个队列来存储这种状态是否出现过。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<unordered_map>
using namespace std;
queue<string> q; //队列来存储各个状态。
unordered_map<string,int> d; //哈希表来存储各个状态到起点的距离。
int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
int bfs(string start){
string end="12345678x";
q.push(start);
d[start]=0;
while(!q.empty()){
auto t=q.front();
q.pop();
if(t==end) return d[t];
int na=t.find('x');//找到x的一维坐标
int x=na/3,y=na%3; //由一维坐标变为二维坐标的技巧
int dis=d[t];
for(int i=0;i<4;i++){
int a=x+dx[i],b=y+dy[i];
if(a>=0&&a<3&&b>=0&&b<3){
swap(t[a*3+b],t[na]);//改变t
if(!d.count(t)){//要看改变之后的t是否已经走过,只有没走过才能保证最短路。
d[t]=dis+1;
q.push(t);
}
swap(t[a*3+b],t[na]);
//要恢复成移动以前的样子,才能进行下一步的尝试。
}
}
}
return -1;
}
int main(){
string start;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
char c;
cin>>c;
start+=c;
}
}
cout<<bfs(start);
return 0;
}