81 lines
2.8 KiB
C++
81 lines
2.8 KiB
C++
#include <bits/stdc++.h>
|
||
|
||
using namespace std;
|
||
const int N = 1e5 + 10; // 开小了会WA
|
||
unordered_map<string, int> dist; // 记录某个字符串,走没有走过,如果走过,那么是走了几步到达的
|
||
unordered_map<string, pair<char, string>> pre; // 记录某个字符串,它的前序操作符是ABC中的哪一个,它的前序字符串是什么
|
||
string start = "12345678"; // 起始态
|
||
string ed; // 目标态,需要输入进来
|
||
string q[N]; // 队列
|
||
|
||
// 交换上下两行
|
||
string A(string t) {
|
||
// 1234 5678---> 8765 4321
|
||
for (int i = 0; i < 4; i++) swap(t[i], t[7 - i]);
|
||
return t;
|
||
}
|
||
|
||
// 将最右边的一列插入到最左边
|
||
string B(string t) {
|
||
// 1234 5678 ---> 4123 6785
|
||
// 4向上冒泡,5向后冒泡
|
||
for (int i = 3; i > 0; i--) swap(t[i], t[i - 1]);
|
||
for (int i = 4; i < 7; i++) swap(t[i], t[i + 1]);
|
||
return t;
|
||
}
|
||
|
||
// 魔板中央的4个数作顺时针旋转
|
||
string C(string t) {
|
||
// 1234 5678 ---> 1724 5368
|
||
/*
|
||
swap(t[1], t[2]) 1234 5678 -> 1324 5678 把第一个不匹配的数字放到合适位置上
|
||
swap(t[5], t[6]) 1324 5678 -> 1324 5768 把第二个不匹配的数字放到合适位置上
|
||
swap(t[1], t[5]) 1324 5768 -> 1724 5368 回到头,再把第一个不匹配的数字放到合适位置上
|
||
*/
|
||
swap(t[1], t[2]), swap(t[5], t[6]), swap(t[1], t[5]);
|
||
return t;
|
||
}
|
||
|
||
void bfs() {
|
||
int hh = 0, tt = -1;
|
||
q[++tt] = start; // 起始点入队列
|
||
|
||
while (hh <= tt) {
|
||
string t = q[hh++];
|
||
if (t == ed) return; // 终点
|
||
|
||
string m[3] = {A(t), B(t), C(t)}; // 按ABC操作后产生的三种字符串
|
||
for (int i = 0; i < 3; i++) {
|
||
string x = m[i];
|
||
if (!dist.count(x)) { // 没有走过
|
||
q[++tt] = x;
|
||
dist[x] = dist[t] + 1;
|
||
pre[x] = {'A' + i, t}; // x的前序:t,是通过'A'+i方式转化过来的
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
int main() {
|
||
char x;
|
||
for (int i = 0; i < 8; i++) cin >> x, ed += x; // 拼接终止状态字符串
|
||
|
||
// 广搜
|
||
bfs();
|
||
|
||
// 输出距离
|
||
cout << dist[ed] << endl;
|
||
|
||
// 输出路径
|
||
string res;
|
||
// 如果操作序列的长度大于0,则在第二行输出字典序最小的操作序列。
|
||
if (dist[ed]) {
|
||
while (true) {
|
||
if (ed == start) break;
|
||
res += pre[ed].first; // 前序操作符,拼接路径,是反的,因为从最后的状态出发,找前序
|
||
ed = pre[ed].second; // 前序字符串
|
||
}
|
||
for (int i = res.size() - 1; i >= 0; i--) cout << res[i];
|
||
}
|
||
return 0;
|
||
} |