题意还是很简单的,但是做起来就不是那么简单了
第一步就是规划好存储方式,还有类似判断的数组
unordered_map<string,int> mp;
unordered_map<string,pair<char,string>> pre;
queue<string> q;
把这个定义出来,其实思路就出来了:
First:
就是先把 三个操作所生成的字符串str
搞出来,然后用bfs进行搜索,如果这个路径还没走过的话即mp.count(str) == 0
,我们就可以执行操作mp[str] = mp[init] + 1
最后再push(str)
;但是我们还要特判一下是否存在已经得到目标序列的情况 即 str == ed
那么此时就可以直接return mp[ed]
了
Then:
就是三个操作了
1.交换俩行 for(int i = 0; i < 4; ++i) swap(map[0][i],map[1][i]);
2.把最后一列插入到第一列
char v1 = map[0][3], v2 = map[1][3];
for (int i = 3; i > 0; --i)
for (int j = 0; j < 2; ++j)
map[j][i] = map[j][i - 1];
map[0][0] = v1, map[1][0] = v2;
3.中央的四个数字顺时针旋转
char v = map[0][1];
map[0][1] = map[1][1];
map[1][1] = map[1][2];
map[1][2] = map[0][2];
map[0][2] = v;
其实吧,我们可以直接设置一个一维数组来存这个序列,这样的话,这些操作就简单很多了(但是别的东西就要改了,想了想还是算了)
Finaly:
得到操作序列的结果
由于是BFS进行搜索,而且我们得到序列的方式是 A -> B -> C
的,再根据队列中的元素是满足二段性的,并且时严格单调的以及BFS搜索的特性,所以我们最后得到的搜索序列就一定是按照字典序从小到大排好序了的;
因此得到代码:
string res;
while (ed != st)
{
res += pre[ed].first;
ed = pre[ed].second;
}
这样最后的得到的res
就是得到的答案了;
全部代码
#include <iostream>
#include <cstring>
#include <queue>
#include <unordered_map>
#include <algorithm>
using namespace std;
unordered_map<string,int> mp;
unordered_map<string,pair<char,string>> pre;
queue<string> q;
char map[2][4];
void set(string state)
{
for (int i = 0; i < 4; ++i) map[0][i] = state[i];
for (int i = 7, j = 0; j < 4; --i, ++j) map[1][j] = state[i];
}
string get()
{
string res;
for (int i = 0; i < 4; ++i) res += map[0][i];
for (int i = 3; i >= 0; --i) res += map[1][i];
return res;
}
string move_1(string state)
{
set(state);
for(int i = 0; i < 4; ++i) swap(map[0][i],map[1][i]);
return get();
}
string move_2(string state)
{
set(state);
char v1 = map[0][3], v2 = map[1][3];
for (int i = 3; i > 0; --i)
for (int j = 0; j < 2; ++j)
map[j][i] = map[j][i - 1];
map[0][0] = v1, map[1][0] = v2;
return get();
}
string move_3(string state)
{
set(state);
char v = map[0][1];
map[0][1] = map[1][1];
map[1][1] = map[1][2];
map[1][2] = map[0][2];
map[0][2] = v;
return get();
}
int bfs(string st, string ed){
if(st == ed) return 0;
q.push(st);
mp[st] = 0;
while(q.size()){
string t = q.front();
q.pop();
string s[3];
s[0] = move_1(t);
s[1] = move_2(t);
s[2] = move_3(t);
for (int i = 0; i < 3; ++i){
if(mp.count(s[i]) == 0){
mp[s[i]] = mp[t] + 1;
pre[s[i]] = {char(i + 'A'),t};
q.push(s[i]);
if(s[i] == ed) return mp[ed];
}
}
}
}
int main(){
string st, ed;
string ans;
for (int i = 0; i < 8; ++i)
{
int ch;
cin >> ch;
ed += char(ch + '0');
}
for (int i = 0; i < 8; ++i) st += char(i + '1');
int res = bfs(st, ed);
cout << res << endl;
while(ed != st)
{
ans += pre[ed].first;
ed = pre[ed].second;
}
reverse(ans.begin(),ans.end());
if(res > 0) cout << ans << endl;
return 0;
}