魔板问题(搜索)

问题 E: 【搜索】魔板问题

时间限制: 1 Sec  内存限制: 64 MB
提交: 23  解决: 6
[提交] [状态] [讨论版] [命题人:admin]

题目描述

据说能使持有者成为世界之主的上古神器隐藏在魔板空间,魔板由8个同样大小的方块组成,每个方块颜色均不相同,按顺时针方向依次写下各方块的颜色代号,例如序列(1,2,3,4,5,6,7,8)即代表图所示的魔板状态。
对于魔板可施加三种不同的操作,分别以A,B,C标识,具体操作方法如图所示。
对于每种可能的状态,这三种基本操作都可以使用。你要编程计算用最少的基本操作完成基本状态到特殊状态的转换,输出基本操作序列。

输入

只有一行,包括8个整数,用空格分开(这些整数在范围 1~8 之间),表示目标状态。

输出

第一行包括一个整数,表示最短操作序列的长度。  

第二行在字典序中最早出现的操作序列,用字符串表示,除最后一行外,每行输出60个字符。 

样例输入

2 6 8 4 5 7 3 1

样例输出

7
BCABCCB

提示

样例的输入目标状态是由BCABCCB这7步操作获得的,如图所示。

map记录每个状态以及是否出现过,bfs跑一边即可。

#include<bits/stdc++.h>
#include<queue>
#include<map>
#include<cstring>
using namespace std;
const int maxn = 5e5 + 5;
map<string, int>digit;
map<string, string>cur;
queue<string>q;
string init, dis;
void swap(char &x, char &y) {
    char t = x;
    x = y;
    y = t;
}
int main() {
     int x;
     for (int k = 1; k <= 8; k++) {
         cin>>x;
         init += (char)(k + '0'), dis += (char)(x + '0');
     }
     q.push(init),
     digit[init] = 1;
     while (!q.empty()) {
          string u = q.front();
          string tmp=u;
          q.pop();
          if (u == dis)break;
          swap(tmp[0], tmp[7]), swap(tmp[1], tmp[6]), swap(tmp[2], tmp[5]), swap(tmp[3], tmp[4]);
          if (!digit[tmp]) {
              q.push(tmp), cur[tmp] = cur[u] + 'A', digit[tmp] = 1;
          }
          tmp[0] = u[3], tmp[1] = u[0], tmp[2] = u[1], tmp[3] = u[2], tmp[7] = u[4], tmp[6] = u[7], tmp[5] = u[6], tmp[4] = u[5];
          if (!digit[tmp]) {
              q.push(tmp), cur[tmp] = cur[u] + 'B', digit[tmp] = 1;
          }
          tmp[0] = u[0], tmp[7] = u[7], tmp[3] = u[3], tmp[4] = u[4], tmp[1] = u[6], tmp[2] = u[1], tmp[5] = u[2], tmp[6] = u[5];
          if (!digit[tmp]) {
              q.push(tmp), cur[tmp] = cur[u] + 'C', digit[tmp] = 1;
          }
     }
     cout << cur[dis].length() << endl << cur[dis] << endl;
     return 0;
}

猜你喜欢

转载自www.cnblogs.com/czy-power/p/10356938.html