【题目来源】
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