写在前面
这个方法我自己测是对的,拿着和蓝桥杯的系统给的那一组免费测试用例去比较也是一样的,但不知道为啥会被判0分,希望有hxd可以可以解答一下。
思路
很暴力的方法,直接用三维列表存储魔方各个面的颜色,然后按指令进行旋转。
魔方存储
每个面用一个二维列表表示,初始魔方的定义如下:
# 定义初始魔方
self.view = [[['g','g'],['g','g']],
[['r','r'],['r','r']],
[['w','w'],['w','w']],
[['b','b'],['b','b']],
[['o','o'],['o','o']],
[['y','y'],['y','y']]]
x轴的正面作为0面,y轴正面作为1面,z轴正面作为2面
x轴的反面作为3面,y轴反面作为4面,z轴反面作为5面
注意
-
旋转时需要旋转对应的顶面和侧面。我在最开始的时候把旋转侧面的函数定义为
sides()
,然后在x、y、z方法里都调用这同一个函数。这样的问题在于:
首先,在x、y中,都出现了用一列的元素去填充一行的元素的情况,而z不需要。
其次,在三个方法里都存在倒序填充的情况,且发生的位置不固定。
-
蓝桥杯的测试系统似乎用不了case语句。
-
top()
实现的是一个令二维列表顺时针旋转的操作。我最初的函数定义如下,这个写法的问题在于temp是arr的浅拷贝:
def top(arr, x0):
temp = arr
what = temp[x0][0][1]
arr[x0][0][0] = temp[x0][1][0]
arr[x0][0][1] = temp[x0][0][0]
arr[x0][1][0] = temp[x0][1][1]
arr[x0][1][1] = temp[x0][0][1]
完整代码
# # Boundary test!
# # n = int(input())
input = list(input()) # 将字符串分割成单个字符,并存储在列表中
l = len(input)
def top(arr, x0):
arr[x0] = [[arr[x0][1][0],arr[x0][0][0]],
[arr[x0][1][1],arr[x0][0][1]]]
def sidesx(arr):
temp0 = arr[2][1]
arr[2][1] = list(arr[4][1][1] + arr[4][0][1])
temp1 = list(arr[1][1][0] + arr[1][0][0])
for i in range(0,2):
arr[1][i][0] = temp0[i]
temp0 = arr[5][1]
arr[5][1] = temp1
for i in range(0,2):
arr[4][i][1] = temp0[i]
def sidesy(arr):
temp0 = list(arr[0][0][1] + arr[0][1][1])
for i in range(0,2):
arr[0][i][1] = arr[5][1-i][1]
temp1 = list(arr[2][0][1] + arr[2][1][1])
for i in range(0,2):
arr[2][i][1] = temp0[i]
temp0 = list(arr[3][0][1] + arr[3][1][1])
for i in range(0,2):
arr[3][i][1] = temp1[1-i]
for i in range(0,2):
arr[5][i][1] = temp0[i]
def sidesz(arr):
temp0 = list(arr[0][0])
temp0.reverse()
arr[0][0] = arr[1][0]
temp1 = arr[4][0]
arr[4][0] = temp0
temp0 = list(arr[3][0])
temp0.reverse()
arr[3][0] = temp1
arr[1][0] = temp0
def replace(color):
if color == 'g':
return '绿'
elif color == 'r':
return '红'
elif color == 'w':
return '白'
elif color == 'b':
return '蓝'
elif color == 'o':
return '橙'
elif color == 'y':
return '黄'
class mofang:
def __init__(self):
# 定义初始魔方
self.view = [[['g','g'],['g','g']],
[['r','r'],['r','r']],
[['w','w'],['w','w']],
[['b','b'],['b','b']],
[['o','o'],['o','o']],
[['y','y'],['y','y']]]
def x(self): # 在x轴正向做顺时针旋转 # top = 0 # sides = 2154
sidesx(self.view) #旋转侧面
top(self.view, 0) # 旋转顶面
def y(self): # 在y轴正向做顺时针旋转 # top = 1 # sides = 0235
sidesy(self.view) #旋转侧面
top(self.view, 1) # 旋转顶面
def z(self): # 在z轴正向做顺时针旋转 # top = 2 # sides = 0431
sidesz(self.view) #旋转侧面
top(self.view, 2) # 旋转顶面
# 定义魔方
m = mofang()
# 按提示旋转魔方
for i in range(0,l):
if input[i] == 'x':
m.x()
elif input[i] == 'y':
m.y()
elif input[i] == 'z':
m.z()
# 生成输出字符串
v = m.view
output = list(v[0][0][1] + v[1][0][0] + v[2][1][1])
output = list(map(replace, output))
output = ''.join(output)
print(output)
更好的方法
在写完之后搜索题目,发现这个博主的写法更简明,而且也可以获得正确的结果。
他的思路是:将二阶魔方划分8个象限,每个象限分xyz三面(或者理解成八个小方块) 。例如,x操作相当于[1,4, 8, 5]这四个小方块在zy方向上的颜色互换,再把它们顺时针旋转。
历届真题 魔方旋转问题【历届真题】【决赛】【高职组】_·L·679的博客-CSDN博客
这个方法我反正是想不出来了:(