题目链接:点击这里
状态怎么存?字符串
怎么判重?基于哈希的unordered_map记录最短距离的同时进行判重
状态怎么转移?一维字符串转换成二维数组,对二维数组按要求进行转换,再转回字符串
怎么记录路径?使用unordered_map记录到达每个状态所采取的操作及其前一个状态,然后倒着往回推出路径。
#include<iostream>
#include<string>
#include<cstring>
#include<unordered_map>
#include<queue>
#include<algorithm>
using namespace std;
unordered_map<string, int> d; // 记录每个状态的最短距离
unordered_map<string, pair<char, string>> pre; // 记录到达每个状态所采取的操作及其前一个状态
int g[2][4];
void str_to_arr(string x)
{
for(int i = 0; i < 4; ++i) g[0][i] = x[i] - '0';
for(int i = 0, j = 7; i < 4; ++i, --j) g[1][i] = x[j] - '0';
}
string arr_to_str()
{
string res;
for(int i = 0; i < 4; ++i) res += char(g[0][i] + '0');
for(int i = 3; i >= 0; i--) res += char(g[1][i] + '0');
return res;
}
string A(string x)
{
str_to_arr(x);
for(int i = 0; i < 4; ++i) swap(g[0][i], g[1][i]);
return arr_to_str();
}
string B(string x)
{
str_to_arr(x);
int a = g[0][3], b = g[1][3];
g[0][3] = g[0][2], g[1][3] = g[1][2];
g[0][2] = g[0][1], g[1][2] = g[1][1];
g[0][1] = g[0][0], g[1][1] = g[1][0];
g[0][0] = a, g[1][0] = b;
return arr_to_str();
}
string C(string x)
{
str_to_arr(x);
int a = g[0][1];
g[0][1] = g[1][1];
g[1][1] = g[1][2];
g[1][2] = g[0][2];
g[0][2] = a;
return arr_to_str();
}
int bfs(string start, string end)
{
queue<string> q;
q.push(start);
d[start] = 0;
while(q.size())
{
auto t = q.front();
q.pop();
string a = A(t); // A操作
if(d.count(a) == 0)
{
q.push(a);
d[a] = d[t] + 1;
pre[a] = {'A', t};
if(a == end) return d[a];
}
string b = B(t); // B操作
if(d.count(b) == 0)
{
q.push(b);
d[b] = d[t] + 1;
pre[b] = {'B', t};
if(b == end) return d[b];
}
string c = C(t); // C操作
if(d.count(c) == 0)
{
q.push(c);
d[c] = d[t] + 1;
pre[c] = {'C', t};
if(c == end) return d[c];
}
}
}
int main()
{
string start = "12345678", end;
for(int i = 0; i < 8; ++i)
{
int x;
cin>>x;
end += char(x + '0');
}
if(start == end) // 特判
{
cout<<"0"<<endl;
return 0;
}
cout << bfs(start, end) << endl;
string res;
while(end != start)
{
res += pre[end].first;
end = pre[end].second;
}
reverse(res.begin(), res.end());
cout << res << endl;
return 0;
}