蓝桥杯-魔方旋转问题-python

写在前面

这个方法我自己测是对的,拿着和蓝桥杯的系统给的那一组免费测试用例去比较也是一样的,但不知道为啥会被判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面

注意

  1. 旋转时需要旋转对应的顶面和侧面。我在最开始的时候把旋转侧面的函数定义为sides(),然后在x、y、z方法里都调用这同一个函数。

    这样的问题在于:

    首先,在x、y中,都出现了用一列的元素去填充一行的元素的情况,而z不需要。

    其次,在三个方法里都存在倒序填充的情况,且发生的位置不固定。

  2. 蓝桥杯的测试系统似乎用不了case语句。

  3. 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博客

这个方法我反正是想不出来了:(

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值