大赢靠德 发表于 2024-11-1 01:17:24

笔试真题——机器人拧魔方模拟

说明:根据遗留的记忆写出来了此篇文章,可能与原文解释有部分出入,但总体思路一致。题目说明:

YYYYRRRRWWWWOOOOGGGGBBBB UUL'
第一行为输入为对应F, R, B, L, U, D面的元素颜色
第二行输入为翻转的标识符
标识符有:F、F'、R、R'、B、B'、L、L'、U、U'、D、D' 。分别为对应明的顺时针翻转和逆时针翻转。带'则为逆时针,不带则为顺时针
输入示意图:


输出说明:
BWBYOORRYGWGORORWGYGWBYB


[*]示例图【无需输出,仅理解】:

输出翻转后最终对应位置F, R, B, L, U, D的颜色序列
题解:


[*]

[*]要理解题目中,每个转动的模拟情况,每个面的转动会影响那些面
[*]旋转面的影响方框【元素】依次是什么,

[*]这里以以U移动举例:

[*]U移动会带动L、F、R、B【顺序可以改,但必须保证前后对应的面相等,因为带动顺序也很关键】

[*]每个面划分为2*2的矩阵,那么,L会影响的元素方位是(0,0) (0,1)。F会影响的也是(0,0) (0,1)
[*]分别模拟出每个面依次对照的影响元素的位置


[*]获取每个影响元素的方位
[*]就可以编码了,难点在于如何理解每一个面的转动以及他所带动的面的元素是什么,每一个面的带动情况是不一样的

 
难度:

复杂度高,找到移动影响序列比较繁琐,编码难度中等
编码


[*]构建常量以及每一个面的两个序列【面移动序列,面中受影响所移动的位置序列】:
Sn, Ni = 0, 1   #常量Sn代表顺时针,Ni代表逆时针
F, R, B, L, U, D = 0,1,2,3,4,5#随意,我只是根据题目来而已
two_d_matrix = [ for i in range(6)]    #批量初始化6个面。每一个面有2*2就是4个元素,这个使用一维数组代替是因为如果使用二级数组会很麻烦

Fr =                      #Xr代表的是 X个面中,移动的4个面序列
Fm = [(2,3), (0, 2), (1, 0), (3, 1)]    #Xm代表的是每个面依次对照的影响元素的位置默认全为顺时针方向【本来应该是(0,0)~(1,1)二进制化就好了】
Lr =
Lm = [(0,2), (0, 2), (0, 2), (3, 1)]
Dr =
Dm = [(2,3), (2, 3), (2, 3), (2, 3)]
Rr =
Rm = [(3,1), (3, 1), (3, 1), (0, 2)]
Ur =
Um = [(1,0), (1, 0), (1, 0), (1, 0)]
Br =
Bm = [(3,1), (1, 0), (0, 2), (2, 3)]
#输入的转动映射
char_to_turn = {'U':(U,Sn), "U'":(U, Ni), "F":(F,Sn),"F'":(F,Ni) , "L":(L,Sn),"L'":(L,Ni),
                "D":(D,Sn) ,"D'":(D,Ni) , "R":(R,Sn), "R'":(R,Ni),"B":(B, Sn), "B'":(B, Ni)}
#全部面的关联面序列以及影响移动框序列,上面的二层抽象,方便后续操作
X_r = {F:Fr, R:Rr, B:Br, L:Lr, U:Ur, D:Dr}
X_m = {F:Fm, R:Rm, B:Bm, L:Lm, U:Um, D:Dm}
[*]将X面翻转(仅单面模拟,不对其他4个移动面进行模拟)以及获取对应值的方法
1 def trun_X_round(round_name:int, S_or_N:int):
2   """
3   将X面进行翻转
4   :param round_name: 输入翻转的面常量
5   :param S_or_N: 输入顺时针或者是逆时针
6   """
7   x_round = two_d_matrix
8   new_round = copy.deepcopy(x_round)#一定要深拷贝,不然好像是会直接修改,因为浅复制是映射到同一个指针
9   if S_or_N == Sn:                  #根据转向去翻转,顺序无所谓,逻辑要一致,这里使用了两个数组来简化,0-3类比为二进制(x,y)就像x={0,1} y={0,1}
10         new_round = x_round
11         new_round = x_round
12         new_round = x_round
13         new_round = x_round
14   else:
15         new_round = x_round
16         new_round = x_round
17         new_round = x_round
18         new_round = x_round
19   # print(new_round)                  #输出测试
20   two_d_matrix = new_round
21   
22 def get_value(X_round:int, idx:tuple):#获取某个索引的值,返回的以面为单位,如["G","G"]
23   return [
24         two_d_matrix], two_d_matrix]
25   ]
[*]翻转其他部分:
1 def trun_other_round_Sn(X_round:int):
2   """
3   翻转X影响的其他部分【受X干扰的面】
4   :param X_round:输入面常量
5   """
6   Xr = X_r         #获取所选面X的关联面序列,下为影响移动框序列
7   Xm_ori = X_m
8   temp_value = , Xm_ori) for i in range(4)]    #批量保存原移动框的值,方便后续覆盖
9   #因为顺时针,所以第一个索引移动后实际上变为最后一个可以理解为循环链表,因为第一个比较特殊,拎出来做一次,理解了这个循环其实就是剩下3个idx的移动
10   two_d_matrix]], two_d_matrix]] = temp_value, temp_value
11   for idx, Xm in enumerate(Xm_ori):
12         if idx > 0:
13             #每次顺时针旋转,当前面的两个元素变为前一个面的两个元素,因为一个面有两个影响元素,temp_value以列表存储,每个存储两个元素列表,不理解调试一下就好了
14             two_d_matrix]] , two_d_matrix]] = temp_value, temp_value
15   # print(two_d_matrix)
16 ​
17   return
18 def trun_other_round_Ni(X_round:int):
19   #就是翻转了一下,就ok了,其他不影响,因为怎么转,点之间都是对应的
20   Xr = list(reversed(X_r))
21   Xm_ori = list(reversed(X_m))
22   temp_value = , Xm_ori) for i in range(4)]
23 ​
24   two_d_matrix]], two_d_matrix]] = temp_value, temp_value
25   for idx, Xm in enumerate(Xm_ori):
26         if idx > 0:
27             two_d_matrix]] , two_d_matrix]] = temp_value, temp_value
28   # print(two_d_matrix)
[*]main函数:
1 if __name__ == '__main__':
2 ​
3   input_list = input()
4   
5   count_input = 0
6   for i in range(6):
7         for k in range(4):#根据输入构造二维矩阵(数组),k和前面设置的常量一一对应
8             two_d_matrix = input_list
9             count_input += 1
10 ​
11   turn_list = []
12   turn_input = input()
13   for idx, turn_one in enumerate(turn_input):
14         if idx != len(turn_input)-1:
15             if turn_input == "'":#当下一个为翻转的字符时加上并存入
16               add_char = turn_one + turn_input
17               turn_list.append(char_to_turn)#映射完存的实际上是(X_round,Sn_or_Ni)
18             else:
19               turn_list.append(char_to_turn)#没有就直接存
20         elif turn_one != "'":
21             turn_list.append(char_to_turn)#末尾不是翻转符那就存入翻转序列
22   for X, angle in turn_list:#遍历翻转数列
23         trun_X_round(X, angle)#先对X本面进行翻转【for内顺序无所谓】
24         if angle == Sn:
25             trun_other_round_Sn(X_round=X)#如果是顺时针就调用顺时针,否则就调用逆时针
26         elif angle == Ni:
27             trun_other_round_Ni(X_round=X)
28 ​
29   for i in two_d_matrix:#构造输出
30         for k in i:
31             print(k,end="")
[*]all code:
1 # 输入示例:带可视化显示
2 # YYYYRRRRWWWWOOOOGGGGBBBB
3 # UUL'
4 import copy
5 Sn, Ni = 0, 1   #常量Sn代表顺时针,Ni代表逆时针
6 F, R, B, L, U, D = 0,1,2,3,4,5#随意,我只是根据题目来而已
7 two_d_matrix = [ for i in range(6)]    #批量初始化6个面。每一个面有2*2就是4个元素,这个使用一维数组代替是因为如果使用二级数组会很麻烦
8 ​
9 Fr =                      #Xr代表的是 X个面中,移动的4个面序列
10 Fm = [(2,3), (0, 2), (1, 0), (3, 1)]    #Xm代表的是每个面依次对照的影响元素的位置默认全为顺时针方向【本来应该是(0,0)~(1,1)二进制化就好了】
11 Lr =
12 Lm = [(0,2), (0, 2), (0, 2), (3, 1)]
13 Dr =
14 Dm = [(2,3), (2, 3), (2, 3), (2, 3)]
15 Rr =
16 Rm = [(3,1), (3, 1), (3, 1), (0, 2)]
17 Ur =
18 Um = [(1,0), (1, 0), (1, 0), (1, 0)]
19 Br =
20 Bm = [(3,1), (1, 0), (0, 2), (2, 3)]
21 #输入的转动映射
22 char_to_turn = {'U':(U,Sn), "U'":(U, Ni), "F":(F,Sn),"F'":(F,Ni) , "L":(L,Sn),"L'":(L,Ni),
23               "D":(D,Sn) ,"D'":(D,Ni) , "R":(R,Sn), "R'":(R,Ni),"B":(B, Sn), "B'":(B, Ni)}
24 #全部面的关联面序列以及影响移动框序列,上面的二层抽象,方便后续操作
25 X_r = {F:Fr, R:Rr, B:Br, L:Lr, U:Ur, D:Dr}
26 X_m = {F:Fm, R:Rm, B:Bm, L:Lm, U:Um, D:Dm}
27 ​
28 def trun_X_round(round_name:int, S_or_N:int):
29   """
30   将X面进行翻转
31   :param round_name: 输入翻转的面常量
32   :param S_or_N: 输入顺时针或者是逆时针
33   """
34   x_round = two_d_matrix
35   new_round = copy.deepcopy(x_round)#一定要深拷贝,不然好像是会直接修改,因为浅复制是映射到同一个指针
36   if S_or_N == Sn:                  #根据转向去翻转,顺序无所谓,逻辑要一致,这里使用了两个数组来简化,0-3类比为二进制(x,y)就像x={0,1} y={0,1}
37         new_round = x_round
38         new_round = x_round
39         new_round = x_round
40         new_round = x_round
41   else:
42         new_round = x_round
43         new_round = x_round
44         new_round = x_round
45         new_round = x_round
46   # print(new_round)                  #输出测试
47   two_d_matrix = new_round
48 ​
49 def get_value(X_round:int, idx:tuple):#获取某个索引的值,返回的以面为单位,如["G","G"]
50   return [
51         two_d_matrix], two_d_matrix]
52   ]
53 ​
54 def trun_other_round_Sn(X_round:int):
55   """
56   翻转X影响的其他部分【受X干扰的面】
57   :param X_round:输入面常量
58   """
59   Xr = X_r         #获取所选面X的关联面序列,下为影响移动框序列
60   Xm_ori = X_m
61   temp_value = , Xm_ori) for i in range(4)]    #批量保存原移动框的值,方便后续覆盖
62   #因为顺时针,所以第一个索引移动后实际上变为最后一个可以理解为循环链表,因为第一个比较特殊,拎出来做一次,理解了这个循环其实就是剩下3个idx的移动
63   two_d_matrix]], two_d_matrix]] = temp_value, temp_value
64   for idx, Xm in enumerate(Xm_ori):
65         if idx > 0:
66             #每次顺时针旋转,当前面的两个元素变为前一个面的两个元素,因为一个面有两个影响元素,temp_value以列表存储,每个存储两个元素列表,不理解调试一下就好了
67             two_d_matrix]] , two_d_matrix]] = temp_value, temp_value
68   # print(two_d_matrix)
69 ​
70   return
71 def trun_other_round_Ni(X_round:int):
72   #就是翻转了一下,就ok了,其他不影响,因为怎么转,点之间都是对应的
73   Xr = list(reversed(X_r))
74   Xm_ori = list(reversed(X_m))
75   temp_value = , Xm_ori) for i in range(4)]
76 ​
77   two_d_matrix]], two_d_matrix]] = temp_value, temp_value
78   for idx, Xm in enumerate(Xm_ori):
79         if idx > 0:
80             two_d_matrix]] , two_d_matrix]] = temp_value, temp_value
81   # print(two_d_matrix)
82 ​
83 if __name__ == '__main__':
84 ​
85   input_list = input()
86 ​
87   count_input = 0
88   for i in range(6):
89         for k in range(4):#根据输入构造二维矩阵(数组),k和前面设置的常量一一对应
90             two_d_matrix = input_list
91             count_input += 1
92 ​
93   turn_list = []
94   turn_input = input()
95   for idx, turn_one in enumerate(turn_input):
96         if idx != len(turn_input)-1:
97             if turn_input == "'":#当下一个为翻转的字符时加上并存入
98               add_char = turn_one + turn_input
99               turn_list.append(char_to_turn)#映射完存的实际上是(X_round,Sn_or_Ni)
100             else:
101               turn_list.append(char_to_turn)#没有就直接存
102         elif turn_one != "'":
103             turn_list.append(char_to_turn)#末尾不是翻转符那就存入翻转序列
104   for X, angle in turn_list:#遍历翻转数列
105         trun_X_round(X, angle)#先对X本面进行翻转【for内顺序无所谓】
106         if angle == Sn:
107             trun_other_round_Sn(X_round=X)#如果是顺时针就调用顺时针,否则就调用逆时针
108         elif angle == Ni:
109             trun_other_round_Ni(X_round=X)
110 ​
111   for i in two_d_matrix:#构造输出
112         for k in i:
113             print(k,end="")
114 ​自己编码的过程:

在我自己编码的途中,纯大脑模拟3维魔方并编码,而且输出如此抽象,实际上是非常困难的,因此我自己编码的时候借助了大模型生成的帮忙的可视化接口(虽然你笔试的时候肯定不能用,我当时也不够时间写出来,找到影响元素的位置序列真tm繁琐)【我命名为draw_cube.py。这个根据自己喜欢来】记得把import 改一下就好,最好复制那个输出就能显示图片了,有图片辅助更好理解
code:
 
1 # 输入示例:带可视化显示
2 # YYYYRRRRWWWWOOOOGGGGBBBB
3 # UUL'
4 import copy
5 import draw_cube#这个是可视化的代码
6 Sn, Ni = 0, 1   #常量Sn代表顺时针,Ni代表逆时针
7 F, R, B, L, U, D = 0,1,2,3,4,5#随意,我只是根据题目来而已
8 two_d_matrix = [ for i in range(6)]    #批量初始化6个面。每一个面有2*2就是4个元素,这个使用一维数组代替是因为如果使用二级数组会很麻烦
9 ​
10 Fr =                      #Xr代表的是 X个面中,移动的4个面序列
11 Fm = [(2,3), (0, 2), (1, 0), (3, 1)]    #Xm代表的是每个面依次对照的影响元素的位置默认全为顺时针方向【本来应该是(0,0)~(1,1)二进制化就好了】
12 Lr =
13 Lm = [(0,2), (0, 2), (0, 2), (3, 1)]
14 Dr =
15 Dm = [(2,3), (2, 3), (2, 3), (2, 3)]
16 Rr =
17 Rm = [(3,1), (3, 1), (3, 1), (0, 2)]
18 Ur =
19 Um = [(1,0), (1, 0), (1, 0), (1, 0)]
20 Br =
21 Bm = [(3,1), (1, 0), (0, 2), (2, 3)]
22 #输入的转动映射
23 char_to_turn = {'U':(U,Sn), "U'":(U, Ni), "F":(F,Sn),"F'":(F,Ni) , "L":(L,Sn),"L'":(L,Ni),
24               "D":(D,Sn) ,"D'":(D,Ni) , "R":(R,Sn), "R'":(R,Ni),"B":(B, Sn), "B'":(B, Ni)}
25 #全部面的关联面序列以及影响移动框序列,上面的二层抽象,方便后续操作
26 X_r = {F:Fr, R:Rr, B:Br, L:Lr, U:Ur, D:Dr}
27 X_m = {F:Fm, R:Rm, B:Bm, L:Lm, U:Um, D:Dm}
28 ​
29 def trun_X_round(round_name:int, S_or_N:int):
30   """
31   将X面进行翻转
32   :param round_name: 输入翻转的面常量
33   :param S_or_N: 输入顺时针或者是逆时针
34   """
35   x_round = two_d_matrix
36   new_round = copy.deepcopy(x_round)#一定要深拷贝,不然好像是会直接修改,因为浅复制是映射到同一个指针
37   if S_or_N == Sn:                  #根据转向去翻转,顺序无所谓,逻辑要一致,这里使用了两个数组来简化,0-3类比为二进制(x,y)就像x={0,1} y={0,1}
38         new_round = x_round
39         new_round = x_round
40         new_round = x_round
41         new_round = x_round
42   else:
43         new_round = x_round
44         new_round = x_round
45         new_round = x_round
46         new_round = x_round
47   # print(new_round)                  #输出测试
48   two_d_matrix = new_round
49 ​
50 def get_value(X_round:int, idx:tuple):#获取某个索引的值,返回的以面为单位,如["G","G"]
51   return [
52         two_d_matrix], two_d_matrix]
53   ]
54 ​
55 def trun_other_round_Sn(X_round:int):
56   """
57   翻转X影响的其他部分【受X干扰的面】
58   :param X_round:输入面常量
59   """
60   Xr = X_r         #获取所选面X的关联面序列,下为影响移动框序列
61   Xm_ori = X_m
62   temp_value = , Xm_ori) for i in range(4)]    #批量保存原移动框的值,方便后续覆盖
63   #因为顺时针,所以第一个索引移动后实际上变为最后一个可以理解为循环链表,因为第一个比较特殊,拎出来做一次,理解了这个循环其实就是剩下3个idx的移动
64   two_d_matrix]], two_d_matrix]] = temp_value, temp_value
65   for idx, Xm in enumerate(Xm_ori):
66         if idx > 0:
67             #每次顺时针旋转,当前面的两个元素变为前一个面的两个元素,因为一个面有两个影响元素,temp_value以列表存储,每个存储两个元素列表,不理解调试一下就好了
68             two_d_matrix]] , two_d_matrix]] = temp_value, temp_value
69   # print(two_d_matrix)
70 ​
71   return
72 def trun_other_round_Ni(X_round:int):
73   #就是翻转了一下,就ok了,其他不影响,因为怎么转,点之间都是对应的
74   Xr = list(reversed(X_r))
75   Xm_ori = list(reversed(X_m))
76   temp_value = , Xm_ori) for i in range(4)]
77 ​
78   two_d_matrix]], two_d_matrix]] = temp_value, temp_value
79   for idx, Xm in enumerate(Xm_ori):
80         if idx > 0:
81             two_d_matrix]] , two_d_matrix]] = temp_value, temp_value
82   # print(two_d_matrix)
83 ​
84 if __name__ == '__main__':
85 ​
86   input_list = input()
87   draw_cube.show_cube_list(input_list)#可视化输入的二阶魔法平面图
88   count_input = 0
89   for i in range(6):
90         for k in range(4):#根据输入构造二维矩阵(数组),k和前面设置的常量一一对应
91             two_d_matrix = input_list
92             count_input += 1
93 ​
94   turn_list = []
95   turn_input = input()
96   for idx, turn_one in enumerate(turn_input):
97         if idx != len(turn_input)-1:
98             if turn_input == "'":#当下一个为翻转的字符时加上并存入
99               add_char = turn_one + turn_input
100               turn_list.append(char_to_turn)#映射完存的实际上是(X_round,Sn_or_Ni)
101             else:
102               turn_list.append(char_to_turn)#没有就直接存
103         elif turn_one != "'":
104             turn_list.append(char_to_turn)#末尾不是翻转符那就存入翻转序列
105   for X, angle in turn_list:#遍历翻转数列
106         trun_X_round(X, angle)#先对X本面进行翻转【for内顺序无所谓】
107         if angle == Sn:
108             trun_other_round_Sn(X_round=X)#如果是顺时针就调用顺时针,否则就调用逆时针
109         elif angle == Ni:
110             trun_other_round_Ni(X_round=X)
111 ​
112   for i in two_d_matrix:#构造输出
113         for k in i:
114             print(k,end="")
115   draw_cube.show_cube()
116 ​
117 #YYYYRRRRWWWWOOOOGGGGBBBB
119 #OBRBWOWRYOYRGYGYWGBRBOWG
120 ​鸣谢:

魔方模拟

来源:https://www.cnblogs.com/io-T-T/p/18519050
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 笔试真题——机器人拧魔方模拟