IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 2017年第八届蓝桥杯 - 省赛 - C/C++大学A组 - C. 魔方状态 -> 正文阅读

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

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

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-09 20:30:33  更:2022-02-09 20:30:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:44:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码