题目考点: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;
}

京公网安备 11010502036488号