トピックリンク:こちらをクリックしてください
状態はどのようにそれを行うには?弦
どのように重い刑?最短距離に基づいて記録しながら、彼らは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;
}