题目考点:STL、 bfs
题目大意:可以看成x上下左右移动最终复原八数码。
题目分析:普通的bfs,不过是用map<string, int>储存状态(这里用的unorderedmap,比较快)
(由于用字符串储存,速度会慢很多,建议改用map<int, int>储存,这里就偷懒了)
#include<unordered_map> #include<algorithm> #include<iostream> #include<cstring> #include<queue> #define tb std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); using namespace std; typedef long long ll; string s1 = ""; queue<string> q; unordered_map<string, string> d; ll dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1} }; //方向 char dc[4] = {'u', 'r', 'd', 'l'}; //方向代号 string bfs(string s){ q.push(s); //初始状态 d[s] = ""; string ends = "12345678x"; //结束状态 while(q.size()){ auto t = q.front(); q.pop(); if(t == ends)return d[t]; //恢复完毕,返回 ll pos = t.find('x'); //找到当前字符串中x的位置 ll x = pos / 3, y = pos % 3; //一维位置转二维坐标 string dt = d[t]; //当前字符串 for(ll i = 0; i < 4; i++){ ll a = x + dir[i][0], b = y + dir[i][1]; if(a >= 0 && a < 3 && b >= 0 && b < 3){ swap(t[a*3+b], t[pos]); //拓展方向 if(!d.count(t)){ d[t] = dt + dc[i]; //当前字符串加上拓展方向的代号 //cout<<t<<' '<<d[t]<<'\n'; //debug状态 q.push(t); } swap(t[a*3+b], t[pos]); //拓展一次后恢复,继续循环下一个状态 } } } return "unsolvable"; //未找到,返回无解 } int main() { char aa[2]; for(ll i = 1; i <= 9; i++){ cin>>aa; //读取字符方式,避免%c读数发生错误(不管什么时候,尽量避免%c) s1 += *aa; } cout<<bfs(s1); return 0; }