2017年第八届蓝桥杯 - 省赛 - C/C++大学A组 - C. 魔方状态

魔方状态

二阶魔方就是只有2层的魔方,只由8个小块组成。

小明很淘气,他只喜欢3种颜色,所有把家里的二阶魔方重新涂了颜色,如下:

前面:橙色
右面:绿色
上面:黄色
左面:绿色
下面:橙色
后面:黄色

请你计算一下,这样的魔方被打乱后,一共有多少种不同的状态。

如果两个状态经过魔方的整体旋转后,各个面的颜色都一致,则认为是同一状态。

请提交表示状态数的整数,不要填写任何多余内容或说明文字。

Ideas

这道题相对来说比较麻烦,而且比赛的时候放在第三题,有点恐怖,建议如果比赛的时候遇到这种填空题,20分钟解决不出来就跳过吧。

如果想要解决这道题,首先面临的第一个问题就是,魔方是三维,我们怎么用计算机语言进行表示。

二阶魔方是由八个块组成的,我们先给这8个块进行编号,上面四个块编号为03,下面四个块编号为47。

然后对于每一个块,都有六个面,其中有三个面是有颜色,另外三个面在魔方内部,是看不见的,所以我们还要对每一个面进行编号。

编号为0的,它的6个面可以表示为['o', 'y', 'x', 'x', 'g', 'x'],其中o表示橙色,y表示黄色,g表示绿色,x表示看不见。

接下来我们就可以用一个二维字符数组表示一个二阶魔方:

cube = [['o', 'y', 'x', 'x', 'g', 'x'],['o', 'y', 'g', 'x', 'x', 'x'],['x', 'y', 'g', 'x', 'x', 'y'],['x', 'y', 'x', 'x', 'g', 'y'],['o', 'x', 'x', 'o', 'g', 'x'],['o', 'x', 'g', 'o', 'x', 'x'],['x', 'x', 'g', 'o', 'x', 'y'],['x', 'x', 'x', 'o', 'g', 'y']]

魔方的状态表示完了之后,接下来就要转动,进行状态转移。

玩过魔方的应该都知道,它的状态转移其实只需要通过三种旋转就可以达到:上面旋转(U)、右面旋转(R)、前面旋转(F)。

假如对于上面旋转(U)操作,首先0、1、2、3四个块的位置要交换。

0 -> 3
3 -> 2
2 -> 1
1 -> 0

然后每个块的6个面编码也要变换:

0 -> 4
4 -> 5
5 -> 2
2 -> 0

同理我们可以得出剩下两种旋转对应的块和面的变换,这样我们就得到了魔方状态转移的步骤。

接下来我们就要进行搜索了,得到魔方的所有状态。

对于某一种状态,它有R、U、F三种操作,通过每一种操作可以得到一个新的状态,而对于每一种状态,要判断一下之前有没有出现过,如果没有,添加到状态集合中,并且后面要基于这种状态继续搜索。

所以这类似于一个BFS的问题,我们需要通过队列来辅助实现。

另外题目中说“如果两个状态经过魔方的整体旋转后,各个面的颜色都一致,则认为是同一状态”,其实就是我们进行去重的依据,还需要定义一个辅助函数进行魔方的整体旋转。

定义函数try_add,传入一个魔方的状态,然后进行整体旋转操作,同样类似于面的旋转操作,不同的是三个面都要进行整体旋转。

Code

Python

from collections import deque
from copy import deepcopydef process_cube(state) -> str:return ''.join([''.join(x) for x in state])def u(state):# 上面顺时针旋转一次def u_cell(cell):# 上面顺时针旋转一次对应的每个块的面编码变化cell[4], cell[5], cell[2], cell[0] = cell[0], cell[4], cell[5], cell[2]for i in [0, 1, 2, 3]:u_cell(state[i])state[0], state[1], state[2], state[3] = state[1], state[2], state[3], state[0]return statedef r(state):# 右面顺时针旋转一次def r_cell(cell):# 右面顺时针旋转一次对应的每个块的面编码变化cell[0], cell[1], cell[5], cell[3] = cell[3], cell[0], cell[1], cell[5]for i in [1, 2, 5, 6]:r_cell(state[i])state[1], state[2], state[5], state[6] = state[5], state[1], state[6], state[2]return statedef f(state):# 前面顺时针旋转一次def f_cell(cell):# 前面顺时针旋转一次对应的每个块的面编码变化cell[1], cell[2], cell[3], cell[4] = cell[4], cell[1], cell[2], cell[3]for i in [0, 1, 4, 5]:f_cell(state[i])state[0], state[1], state[4], state[5] = state[4], state[0], state[5], state[1]return statedef u_whole(state):# 上+下面顺时针旋转一次def u_d_cell(cell):# 上+下面顺时针旋转一次对应的每个块的面编码变化cell[4], cell[5], cell[2], cell[0] = cell[0], cell[4], cell[5], cell[2]for i in range(8):u_d_cell(state[i])state[0], state[1], state[2], state[3] = state[1], state[2], state[3], state[0]state[4], state[5], state[6], state[7] = state[5], state[6], state[7], state[4]return statedef r_whole(state):# 右+左面顺时针旋转一次def r_l_cell(cell):# 右+左面顺时针旋转一次对应的每个块的面编码变化cell[0], cell[1], cell[5], cell[3] = cell[3], cell[0], cell[1], cell[5]for i in range(8):r_l_cell(state[i])state[1], state[2], state[5], state[6] = state[5], state[1], state[6], state[2]state[0], state[3], state[4], state[7] = state[4], state[0], state[7], state[3]return statedef f_whole(state):# 前+后面顺时针旋转一次def f_b_cell(cell):# 前+后面顺时针旋转一次对应的每个块的面编码变化cell[1], cell[2], cell[3], cell[4] = cell[4], cell[1], cell[2], cell[3]for i in range(8):f_b_cell(state[i])state[0], state[1], state[4], state[5] = state[4], state[0], state[5], state[1]state[3], state[2], state[7], state[6] = state[7], state[3], state[6], state[2]return statedef try_add(state):for _ in range(4):state = u_whole(deepcopy(state))for _ in range(4):state = r_whole(deepcopy(state))for _ in range(4):state = f_whole(deepcopy(state))if process_cube(state) in states:returnstates.add(process_cube(state))queue.append(state)if __name__ == '__main__':cube = [['o', 'y', 'x', 'x', 'g', 'x'],['o', 'y', 'g', 'x', 'x', 'x'],['x', 'y', 'g', 'x', 'x', 'y'],['x', 'y', 'x', 'x', 'g', 'y'],['o', 'x', 'x', 'o', 'g', 'x'],['o', 'x', 'g', 'o', 'x', 'x'],['x', 'x', 'g', 'o', 'x', 'y'],['x', 'x', 'x', 'o', 'g', 'y']]queue, states = deque(), set()queue.append(cube)states.add(process_cube(cube))while queue:front = queue.popleft()u_state = u(deepcopy(front))try_add(u_state)r_state = r(deepcopy(front))try_add(r_state)f_state = f(deepcopy(front))try_add(f_state)print(len(states))

Answer: 229878

2017年第八届蓝桥杯 - 省赛 - C/C++大学A组 - C. 魔方状态相关推荐

  1. 2017年第八届蓝桥杯 - 省赛 - C/C++大学A组 - G. 正则问题

    描述:正则问题 考虑一种简单的正则表达式: 只由 x ( ) | 组成的正则表达式. 小明想求出这个正则表达式能接受的最长字符串的长度. 例如 ((xx|xxx)x|(x|xx))xx 能接受的最长字 ...

  2. 2017年第八届蓝桥杯 - 国赛 - C/C++大学B组 - A. 36进制

    36进制 对于16进制,我们使用字母A-F来表示10及以上的数字. 如法炮制,一直用到字母Z,就可以表示36进制. 36进制中,A表示10,Z表示35,AA表示370 你能算出 MANY 表示的数字用 ...

  3. 2017年第八届蓝桥杯 - 省赛 - C/C++大学A组 - B. 跳蚱蜢

    题目 如图所示: 有9只盘子,排成1个圆圈. 其中8只盘子内装着8只蚱蜢,有一个是空盘. 我们把这些蚱蜢顺时针编号为 1~8 每只蚱蜢都可以跳到相邻的空盘中, 也可以再用点力,越过一个相邻的蚱蜢跳到空 ...

  4. 2017年第八届蓝桥杯 - 省赛 - C/C++大学A组 - A. 迷宫

    标题:迷宫 X星球的一处迷宫游乐场建在某个小山坡上,它是由10x10相互连通的小房间组成的,房间的地板上写着一个很大的字母. 我们假设玩家是面朝上坡的方向站立,则: L表示走到左边的房间, R表示走到 ...

  5. 2021年第十二届蓝桥杯 - 省赛 - C/C++大学A组 - D.路径

    2021年第十二届蓝桥杯 - 省赛 - C/C++大学A组 - D.路径 Ideas 算法:最短路径 数据结构:图 思路:根据规则构图,单源最短路径Dijkstra算法. 首先构图其实很简单,就是按照 ...

  6. 2021年第十二届蓝桥杯 - 省赛 - C/C++大学B组 - I.双向排序

    2021年第十二届蓝桥杯 - 省赛 - C/C++大学B组 - I.双向排序 Ideas 题目中给出了两种操作: 当 pi = 0 时,表示将 a1, a2, · · · , aqi 降序排列: 当 ...

  7. 2019 第十届蓝桥杯省赛C/C++大学B组 试题+题解

    第十届蓝桥杯省赛C/C++大学B组 试题+题解 第十届蓝桥杯大赛软件类省赛 C/C++ 大学 B 组 考生须知 考试开始后,选手首先下载题目,并使用考场现场公布的解压密码解压试 题. 考试时间为 4 ...

  8. 2017年第八届蓝桥杯省赛B组 C/C++

    2017.4.8,第八届蓝桥杯初赛,时隔一月多,才写个题解,贼尴尬...这学期竞赛多,PAT,天梯赛初决赛,蓝桥杯初决赛,ACM省赛,加上课程也多,真是累成狗了,蓝桥初赛后就一直学习课程,和小伙伴一起 ...

  9. 2017年第八届蓝桥杯省赛题目python解答(更新中)

    目录 1. 迷宫 2. 跳蚱蜢 3. 魔方状态 4. 方格分割 5. 正则表达式 6. 包子凑数 ·· 1. 迷宫 思路:使用暴力的方法来求解,对于每一个玩家,计算他能否走出去.对于一些走不出去的玩家 ...

最新文章

  1. linux杂七杂八整理
  2. Ueditor的配置及使用
  3. html网页如何获取后台数据库的数据(html + ajax + php + mysql)
  4. ubuntu16.04 + kinetic +turtlebot2配置
  5. ACM-ICPC 2018 徐州赛区网络预赛G (单调队列)
  6. Java EE中的重新验证(java.util.regex.Pattern)
  7. AOP的XML架构、AOP的@AspectJ
  8. 深入理解:overflow:hidden——溢出,坍塌,清除浮动
  9. notepad++格式化插件安装
  10. dlna和miracast可以共存吗_Airplay、Miracast、DLNA传输原理的底层搭建
  11. 统计字符串中某字符出现次数
  12. iMindMap12思维导图如何制作导图教程
  13. CSDN下载频道于2014年7月17日改版,23日-24日系统维护
  14. AssetBundle接口详解与优化
  15. 16.微信登入与授权
  16. Windows7旗舰版SP1_32位2018.10(办公版)
  17. Unity协程(Coroutine)之yield和迭代原理分析
  18. 语言(Language)和语法(Syntax)简述
  19. swift语言前景_swift语言从天而降,作为ios程序猿,我们如果面对?
  20. 相亲交友v6.7.7

热门文章

  1. PHP与SQL注入攻击
  2. 浏览器工作原理(四):浏览器事件解读
  3. Java模板引擎之freemarker简介
  4. VS IISExpress REST DELETE 405 Method Not Allowed
  5. muse ui tabs背景颜色字体颜色
  6. 每一对顶点之间的最短路径
  7. 巧用EditPlus包含VS2010网站项目资源
  8. oracle11g 隐藏参数_oracle隐含参数的查看与修改
  9. pandas显示全部数据内容_1行Python代码就能挖掘数据!这个库太神奇啦!
  10. python的类变量和成员变量用法_Python面向对象程序设计类变量与成员变量、类方法与成员方法用法分析...