【题目来源】
https://www.luogu.com.cn/problem/P1379
【题目描述】
在 3×3 的棋盘上,摆有八个棋子,每个棋子上标有 1 至 8 的某一数字。棋盘中留有一个空格,空格用 0 来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为 123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
【输入格式】
输入初始状态,一行九个数字,空格用 0 表示。
【输出格式】
只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数。保证测试数据中无特殊无法到达目标状态数据。
【输入样例】
283104765
【输出样例】
4
【样例解释】
图中标有 0 的是空格。绿色格子是空格所在位置,橙色格子是下一步可以移动到空格的位置。如图所示,用四步可以达到目标状态。
并且可以证明,不存在更优的策略。
【算法分析】
unordered_map(哈希表):
https://cplusplus.com/reference/unordered_map/unordered_map/
https://cplusplus.com/reference/unordered_map/unordered_map/count/
【算法代码】
#include <bits/stdc++.h>
using namespace std;
int dx[]= {-1,0,1,0};
int dy[]= {0,1,0,-1};
string ans="123804765";
int bfs(string s) {
unordered_map<string, int> dis;
dis[s]=0;
queue<string> q;
q.push(s);
while(q.size()) {
string t=q.front();
q.pop();
if(t==ans) return dis[t];
int d=dis[t];
int k=t.find('0');
int x=k/3,y=k%3;
for(int i=0; i<4; i++) {
int tx=x+dx[i],ty=y+dy[i];
if(tx>= 0 && tx<3 && ty>=0 && ty<3) {
swap(t[k],t[tx*3+ty]);
if(!dis.count(t)) {
q.push(t);
dis[t]=d+1;
}
swap(t[k],t[tx*3+ty]);
}
}
}
return -1;
}
int main() {
string s;
cin>>s;
cout<<bfs(s);
}
/*
in:283104765
out:4
*/
【参考文献】
https://www.cnblogs.com/DM11/p/17001294.html
https://www.acwing.com/blog/content/5209/
https://www.cnblogs.com/sherluoke/p/15048778.html
https://blog.csdn.net/hnjzsyjyj/article/details/134756634
https://www.cnblogs.com/zufezzt/p/5659276.html
https://zhuanlan.zhihu.com/p/643917734
https://blog.csdn.net/Archerrrrr/article/details/110375815
https://blog.csdn.net/qq_60236552/article/details/119039352