A21390. 拼图拼接问题
题目描述
拼图拼接问题
题目描述
小利准备将 n 块拼图从左到右进行拼接,每块拼图原本为大小一致的正方形卡片,每条边都做了改变,共有 8 种不同的边,使用编号 1 - 8 表示。每块拼图使用其 上、右、下、左 四条边的编号来表示。
例如,下面两块拼图共有 8 种不同的边,左边的拼图用 1234 表示,右边的拼图用 5678 表示:

拼图规则
1. 在拼图中:

• 1 号边只能与 8 号边拼接
• 2 号边只能与 7 号边拼接
• 3 号边只能与 6 号边拼接
• 4 号边只能与 5 号边拼接
2. 你可以将每块拼图顺时针旋转 0 度、90 度、180 度、270 度来进行拼图(不能翻转到另一面进行拼图)。例如,同一块拼图旋转不同度数时的效果如下图所示:

• 旋转 0 度:上边为 1,右边为 2,下边为 3,左边为 4
• 旋转 90 度:上边为 4,右边为 1,下边为 2,左边为 3
• 旋转 180 度:上边为 3,右边为 4,下边为 1,左边为 2
• 旋转 270 度:上边为 2,右边为 3,下边为 4,左边为 1
3. 除第一块拼图外,下一块拼图只能拼在已拼接拼图的最右边。
注:
在各种拼法中,只要有任意一个相同位置上的拼图不一致,或拼图相同但旋转的方向不一致,都算不同的拼法。
本题中,n 块拼图是不同的,不存在以下两种情况:
1. 同一块拼图,旋转 90 度、180 度、270 度后,不会出现与 0 度相同的情况。
2. 任意两块拼图,不会出现其中一块拼图旋转后与另一块相同。
例如:n = 3;3 块拼图分别是 4524、6134、3872,如下图所示:

一共有 4 种不同的拼法,如下图所示:

输入描述
1. 第一行输入一个整数 n(2 ≤ n ≤ 8),表示拼图的块数;
2. 第二行输入 n 个长度为 4 的字符串,字符串仅包含数字 1 - 8,字符串之间以一个空格隔开,每个字符串从左至右的 4 个数字依次表示该块拼图 上、右、下、左 四条边的编号。
输出描述
输出一个整数,表示多少种不同的拼法。
输入样例
3
4524 6134 3872输出样例
4参考答案
# 3
# 4524 6134 3872
import itertools as tool
n = int(input())#卡牌数据
cardList = input().split()# 排列情况
p1List = tool.permutations(cardList, n)#建立匹配的字典映射关系
matchMap={'1':'8','8':'1','2':'7','7':'3','3':'6','6':'3','4':'5','5':'4'}#方案数
ans=0# 旋转对应次数得到的结果
def turnRightResult(p_x, time): # 旋转次数
if time == 0: # 0次直接返回
return p_x
elif time == 1:
return p_x[3]+p_x[0]+p_x[1]+p_x[2]
elif time == 2:
return p_x[2]+p_x[3]+p_x[0]+p_x[1]
else:
return p_x[1]+p_x[2]+p_x[3]+p_x[0]
for p in p1List: # print(p)
p_0=p[0]
p_1=p[1]
p_2=p[2]
for p_0_time in range(3): #第一个取右边的,下标为1
middleNum1=turnRightResult(p_0, p_0_time)
middleNum1_right = middleNum1[1]
for p_1_time in range(3): # 第二个取左边的,下标为3
middleNum2= turnRightResult(p_1, p_1_time)
middleNum2_left = middleNum2[3]
middleNum2_right = middleNum2[1]
for p_2_time in range(3): # 第三个取左边的,下标为3
middleNum3 = turnRightResult(p_2, p_2_time)
middleNum3_left = middleNum3[3]
middleNum3_right = middleNum3[1]
# 能够拼凑上
#第一个数右边接上第二个左边
#第二个数右边街上第三个数左边
if matchMap[middleNum1_right] == middleNum2_left and matchMap[middleNum2_right] == middleNum3_left:
ans += 1
print(ans)