题目地址:方格分割
读完题不要被吓到,其实就是一道略微注重细节的DFS模板题,细节在哪呢?
既然是求两部分的形状完全相同的分割方法,那我们把方格置0,再用for循环对某一部分置1,以此点不断深入直接求出所有可行解即可,这就是我们的大体思路,以此先写出相应代码:
grid = [[0] * 6 for _ in range(6)]
ans = 0
move = [(1, 0), (-1, 0), (0, 1), (0, -1)]
def check(x, y): # DFS深度遍历求解
global ans
if x == 0 or y == 0 or x == 6 or y == 6: # 达到完成条件,答案+1跳出递归
ans += 1
return
for i in range(4):
xx = x + move[i][0]
yy = y + move[i][1]
if xx < 0 or yy < 0 or xx > 6 or yy > 6 or grid[xx][yy] == 1:
continue
check(xx, yy) # 深度递归遍历
check(0, 0) # 从0, 0点开始循环遍历
print(ans)
此时我们发现我们无法判断这个解是不是对应的正解,而在其构成后再去判断未免太麻烦,对此,我们知道其是对称的图形,所以我们在对一个点置1时可以把其对称的点置1,则所得的最终图形必然是对称的,另外,在首次check时,我们不能直接带入(0, 0)这一点,这样就代表每次剪裁必须通过此点,但是也有其他剪裁情况并不包括此点,经观察我们可以发现对称图像其中心四点必须至少经过一次,所以我们要从(3, 3)这一点开始递归,因为正方形是可以旋转的,所以中心四点经过旋转其坐标可以表示为(3, 3),最后输出答案也要//4,因为正方形的四个点是对称的。
完整代码:
grid = [[0] * 7 for _ in range(7)] # 开6个会导致越界,开多了没事,边界函数界定一下即可
ans = 0
move = [(1, 0), (-1, 0), (0, 1), (0, -1)]
def check(x, y): # DFS深度遍历求解
global ans
if x == 0 or y == 0 or x == 6 or y == 6:
ans += 1
return
grid[x][y] = 1
grid[6 - x][6 - y] = 1 # 对称点
for i in range(4):
xx = x + move[i][0]
yy = y + move[i][1]
if xx < 0 or yy < 0 or xx > 6 or yy > 6 or grid[xx][yy] == 1:
continue
check(xx, yy)
grid[x][y] = 0 # 递归完后归0,以便下一次递归另一种剪裁方式
grid[6 - x][6 - y] = 0
check(3, 3) # 中间四格必须要剪到,而其余边缘格子只是其中的一种情况
print(ans // 4)