题目描述:

Rubik 先生在发明了风靡全球的魔方之后,又发明了它的二维版本——魔板。

这是一张有 8 个大小相同的格子的魔板:

1 2 3 4
8 7 6 5

我们知道魔板的每一个方格都有一种颜色。

这 8 种颜色用前 8 个正整数来表示。

可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列。

对于上图的魔板状态,我们用序列 (1,2,3,4,5,6,7,8)来表示,这是基本状态。

这里提供三种基本操作,分别用大写字母 A,B,C 来表示(可以通过这些操作改变魔板的状态):

A:交换上下两行;
B:将最右边的一列插入到最左边;
C:魔板中央对的4个数作顺时针旋转。

下面是对基本状态进行操作的示范:

A:

8 7 6 5
1 2 3 4

B:

4 1 2 3
5 8 7 6

C:

1 7 2 4
8 6 3 5

对于每种可能的状态,这三种基本操作都可以使用。

你要编程计算用最少的基本操作完成基本状态到特殊状态的转换,输出基本操作序列。

注意:数据保证一定有解。

输入格式

输入仅一行,包括 8 个整数,用空格分开,表示目标状态。

输出格式

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

如果操作序列的长度大于0,则在第二行输出字典序最小的操作序列。

数据范围

输入数据中的所有数字均为 1 到 8 之间的整数。

输入样例:

2 6 8 4 5 7 3 1

输出样例:

7
BCABCCB

分析:

本题是求从一种状态到另一种状态的最小转化步数,并且还要输出每次转化进行的操作,BFS除了能够解决边权相同的最短路径问题,也可以解决从一种状态转移到另一种状态的最小步数问题。只需要将起始状态放入队列,然后将队头状态能够到达的状态再依次加入队列,以此类推,直至搜索到结束状态为止。本题只能从开始状态开始搜索,这里的三种操作ABC,尽管状态s经过A操作转化为状态t,状态t再做一次A操作又能够回到状态s,A操作是可逆的,但是BC操作都是不可逆的,因此不能倒着搜索。

本题的难度在于状态的表示和存储。首先是如何存储当前状态,直接用个八位的整数,用个vector,或者用个普通数组都是可以的,但是这些表示不便于存储状态附带的信息或者不方便转化成其他状态,比如用八位数的整数存储状态,那么还需要手动分离出每一位才能进行ABC操作,比较麻烦,用vector或者数组存储后面再表示状态附带的信息,比如步数和上一步状态时就很不方便了。所以这里用string存储状态。然后考虑如何实现ABC三种操作,只需要观察每种操作对各个位置数的影响即可,然后用string的库函数重新拼凑就行了,三种操作的实现可以参考代码。接下来考虑步数和上一步状态信息的存储,string类型对应的步数自然可以用unordered_map<string,int>进行存储,而上一步的状态以及从上一步转化到这一步的操作类型就可以用unordered_map<string,pair<char,string>>进行存储,char存储操作类型,后面的string存储上一步的状态。具体的实现细节见代码:

#include <iostream>
#include <unordered_map>
#include <algorithm>
#include <string>
using namespace std;
string q[40500],start = "12345678";
unordered_map<string,int> d;
unordered_map<string,pair<char,string> > pre;
string move1(string s){return string(s.rbegin(),s.rend());
}
string move2(string s){return s[3] + s.substr(0,3) + s.substr(5,3) + s[4];
}
string move3(string s){return s.substr(0,1)+s[6]+s[1]+s.substr(3,2)+s[2]+s[5]+s[7];
}
void bfs(string end){int hh = 0,tt = 0;q[0] = start,d[start] = 0;while(hh <= tt){string t = q[hh++],s[3];s[0]=move1(t),s[1]=move2(t),s[2]=move3(t);for(int i = 0;i < 3;i++){if(!d.count(s[i])){d[s[i]] = d[t] + 1;pre[s[i]] = {'A' + i,t};if(s[i] == end)   return;q[++tt] = s[i];}}}
}
int main(){int n;string res,end;for(int i = 0;i < 8;i++){cin>>n;end += '0' + n;}bfs(end);cout<<d[end]<<endl;while(start != end){res += pre[end].first;end = pre[end].second;}cout<<string(res.rbegin(),res.rend());return 0;
}

AcWing 1107 魔板相关推荐

  1. 算法提高课-搜索-最小步数模型-AcWing 1107. 魔板:bfs、复杂、八数码类似的题目

    题目分析 来源:acwing 分析: 最小步数模型常用哈希 按照ABC的顺序来搜,得到的是字典序最小的. 这里整幅"图"是一个状态, 装进一个字符串中,然后一个状态改变到另一个状态 ...

  2. java51游戏_Java作业实践(一)魔板游戏

    课题:魔板游戏 一.课设要求 1.基本功能 (1)游戏规则 一个3×3的魔板,有一个格子是空的,其他格子内随机放置1-8共8个编号的方块,通过单击任意一个与空格子相邻的方块可以把该方块移入空格子,不断 ...

  3. P2730 魔板 Magic Squares

    不看题解肯定不会系列... 这道题可以用Cantor展开解决. Cantor展开可以求出一个数组是在全排列中的第几个. 具体怎么操作自己百度. Cantor展开的公式是:\(a[1] * (n - 1 ...

  4. 【题解】Luogu P2730 魔板

    蒟蒻的第一道蓝题--好像也没有蓝的程度 一篇无STL的超弱题解(入门写法无误了QAQ 传送门 很经典的一道BFS 这是初始状态. 操作A 操作B 操作C 思路1 不使用cantor展开的情况 1. 对 ...

  5. 洛谷P2730 [IOI]魔板 Magic Squares

    题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题目描述 我们知道魔板的每一个方格都有一种颜色.这8种颜 ...

  6. Magic Squares 魔板 (BFS+HASH)

    Description 在成功地发明了魔方之后,拉比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 我们知道魔板的每一个方格都有一种颜色.这8 ...

  7. HDU 1430 魔板(康托展开+BFS+预处理)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  8. hdu.1430.魔板(bfs + 康托展开)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  9. 魔板(洛谷-P2730)

    题目描述 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 我们知道魔板的每一个方格都有一种颜色.这8种颜色用前8个 ...

  10. 魔板(信息学奥赛一本通-T1449)

    [题目描述] 在成功地发明了魔方之后,拉比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 我们知道魔板的每一个方格都有一种颜色.这8种颜色用前 ...

最新文章

  1. 有不含有重复数字的数组构造二叉树_Leetcode刷题记录:构建最大数二叉树
  2. [SAP-SD]Sales Order 中的User Exit开发
  3. 批量导入sql文件。
  4. 后台服务程序开发模式(一)
  5. 重温Observer模式--热水器·改(转载)
  6. Bootstrap3 的新特性
  7. java多线程基础篇第一篇-JMM
  8. mysql的txid是什么_mysql-存储引擎
  9. idea取消vim模式
  10. 微信开发源代码详细分析-微信开发教程6
  11. Qt Data Visualization 3D可视化
  12. 人工智能新闻写作软件3.0时代来临
  13. bugku-writeup-MISC-宽带信息泄露
  14. c语言赋值语句逗号,C++中赋值运算符与逗号运算符的用法详解
  15. 世界上最健康的作息时间表健康十不易
  16. 解决 primordials is not defined 问题
  17. 安卓日志点击无反应_日志MIUI 12 20.9.22 内测更新综合资讯 “小米营业厅”内测...
  18. 史密斯探测证实,BioFlash可检出空气中的SARS-CoV-2变异株,包括德尔塔和德尔塔+
  19. Cadence PCB仿真使用Allegro PCB SI生成振铃ringing仿真报告及报告导读图文教程
  20. 253:丛林中的路——最小生成树Prim

热门文章

  1. <blockquote>标签 自定义样式
  2. 用电器开关应该接在火线上还是零线上
  3. OrCAD DSN文件无故消失解决办法
  4. 【推荐】男篮之恨,以cxk可解?
  5. 生如夏花之灿烂,死如秋叶之静美
  6. 红黑联盟mysql,红黑联盟官网被人恶意留下后门
  7. 建筑工程测量与测绘毕业论文范文
  8. c++个人银行账户管理3
  9. pyspark运行ALS推荐算法
  10. als算法参数_spark ALS算法