AcWing 1107. 魔板
原题链接
简单
作者:
minux
,
2020-05-22 11:23:19
,
所有人可见
,
阅读 490
#include <bits/stdc++.h>
using namespace std;
typedef pair<char, string> PCS;
#define fi first
#define se second
char G[2][4];
unordered_map<string, int> dist;
unordered_map<string, PCS> pre;
string _get(){
string res;
for(int i=0; i<4; ++i) res+=G[0][i];
for(int i=3; i>=0; --i) res+=G[1][i];
return res;
}
void _set(string state){
for(int i=0; i<4; ++i) G[0][i]=state[i];
for(int i=3, j=4; i>=0; --i, ++j) G[1][i]=state[j];
}
int main(){
char x;
string start, end;
for(int i=0; i<8; ++i){cin>>x; end+=x;} // 存储目标状态
for(int i=0; i<8; ++i) start+=i+'1'; // 存储起始状态
function<string(string)> move0=[&](string st){ // A:交换上下两行
_set(st);
for(int i=0; i<4; ++i) swap(G[0][i], G[1][i]);
return _get();
};
function<string(string)> move1=[&](string st){ // B:最右列插入到最左侧
_set(st);
char e0=G[0][3], e1=G[1][3];
for(int i=3; i>0; --i)
for(int j=0; j<2; ++j)
G[j][i]=G[j][i-1];
G[0][0]=e0;
G[1][0]=e1;
return _get();
};
function<string(string)> move2=[&](string st){ // C:中间4个数进行顺时针旋转
_set(st);
char e=G[0][1];
G[0][1]=G[1][1];
G[1][1]=G[1][2];
G[1][2]=G[0][2];
G[0][2]=e;
return _get();
};
function<void(string, string)> bfs=[&](string start, string end){
if(start==end) return;
queue<string> q;
q.push(start);
dist[start]=0;
while(!q.empty()){
auto t=q.front();
q.pop();
string move[3];
move[0]=move0(t);
move[1]=move1(t);
move[2]=move2(t);
for(int i=0; i<3; ++i){
string m=move[i];
if(dist.count(m)==0){
dist[m]=dist[t]+1;
pre[m]={char(i+'A'), t};
if(m==end) break;
q.push(m);
}
}
}
};
bfs(start, end);
cout<<dist[end]<<endl;
string res;
while(end!=start){
res+=pre[end].fi;
end=pre[end].se;
}
reverse(res.begin(), res.end());
if(res.size()) cout<<res<<endl;
return 0;
}