您当前的位置: 首页 >  蓝桥杯

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

发布时间:2022-02-08 14:04:25 ,浏览量:0

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 deepcopy def 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 state def 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 state def 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 state def 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 state def 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 state def 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 state def 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: return states.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
关注
打赏
1688896170
查看更多评论

暂无认证

  • 0浏览

    0关注

    108697博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0512s