AcWing 1107. 魔板-直接操作string变换状态
原题链接
简单
作者:
现代修士o_O
,
2021-07-22 12:26:40
,
所有人可见
,
阅读 225
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <queue>
using namespace std;
unordered_map<string, int> dist; unordered_map<string,pair<char,string>> pre;
string start = "12345678";
string goal;
string move0(string t)
{
reverse(t.begin(), t.end());
return t;
}
string move1(string t)
{
for (int i = 3; i ; i -- ) swap(t[i], t[i - 1]);
for (int i = 4; i < 7; i ++ ) swap(t[i], t[i + 1]);
return t;
}
string move2(string t)
{
swap(t[1], t[2]);//交换3个位置,相当于顺时针
swap(t[5], t[6]);
swap(t[1], t[5]);
return t;
}
//规定从魔板的左上角开始,沿顺时针方向依次取出整数
int bfs()
{
if (start == goal) return 0;
dist[start] = 0;
queue<string> q;
q.push(start);
while (q.size())
{
auto t = q.front(); q.pop();
string m[3];
m[0] = move0(t);
m[1] = move1(t);
m[2] = move2(t);
for (int i = 0; i < 3; i ++ )
for (int i = 0; i < 3; i ++ )
{
string str = m[i];
if (dist.count(str) == 0)
{
dist[str] = dist[t] + 1;
q.push(str);
pre[str] = {'A' + i, t};
if (str == goal) return dist[goal];
}
}
}
return -1;
}
int main()
{
int x;
for (int i = 0; i < 8; i ++ )
{
cin >> x;
goal += char(x + '0');
}
cout << bfs() << endl;
string res;
while (goal!=start)
{
res += pre[goal].first;
goal = pre[goal].second;
}
reverse(res.begin(), res.end());
//如果操作序列的长度大于0,则在第二行输出字典序最小的操作序列。
if (res.size()) cout << res << endl;
return 0;
}