算法提高之魔板
-
核心思想:最短路模型
- 将所有状态存入队列 更新步数 同时记录前驱状态
-
#include <iostream>#include <cstring>#include <algorithm>#include <unordered_map>#include <queue>using namespace std;string start="12345678";char g[2][4]; //存矩阵unordered_map<string,pair<char,string>> pre; //第一维当前状态 第二维(走法,前驱状态)unordered_map<string,int> dist;void set(string state) //将字符串放入矩阵{for(int i=0;i<4;i++) g[0][i] = state[i];for(int i=7,j=0;j<4;i--,j++) g[1][j] = state[i];}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;}string move0(string state) //走法A{set(state);for(int i=0;i<4;i++) swap(g[0][i],g[1][i]);return get();}string move1(string state) //走法B{set(state);int v0 = g[0][3],v1 = g[1][3];for(int i=3;i>0;i--){g[0][i] = g[0][i-1];g[1][i] = g[1][i-1];}g[0][0] = v0,g[1][0] = v1;return get();}string move2(string state) //走法C{set(state);int v = g[0][1];g[0][1] = g[1][1];g[1][1] = g[1][2];g[1][2] = g[0][2];g[0][2] = v;return get();}int bfs(string start,string end){if(start == end) return 0;queue<string> q;q.push(start);dist[start] = 0;while(!q.empty()){auto t = q.front();q.pop();string m[3];m[0] = move0(t);m[1] = move1(t);m[2] = move2(t);for(int i=0;i<3;i++){if(!dist.count(m[i])){dist[m[i]] = dist[t] + 1;pre[m[i]] = {'A' + i,t}; //存前驱q.push(m[i]);if(m[i] == end) return dist[end];}}}return -1;}int main(){int x;string end;for(int i=0;i<8;i++){cin>>x;end+=char(x+'0');}int step = bfs(start,end);cout<<step<<endl;string res;while(end != start){res += pre[end].first;end = pre[end].second;}reverse(res.begin(),res.end()); //走法是倒过来的 倒置一下if(step > 0) cout<<res<<endl;}