Python题解—方格分隔
题目描述
给定一个6×6 的方格,沿着格子的边线剪开成两部分。 要求这两部分的形状完全相同。
如下就是三种可行的分割法。
试计算: 包括这 3 种分法在内,一共有多少种不同的分割方法。 注意:旋转对称的属于同一种分割法。
问题分析:
已知:一个由方块组成的正方形
未知:怎么分隔能获得两个形状相同的方块
首先是进行问题的转化,根据正方形的对称性,其实我们分隔方块只要考虑一半:从中心点引出一条割出去的线。找到一共有多少个这样的线,再根据正方形的对称性,除以4,就可以得到一共有多少种这样的线。
所以目前问题就变为了:从中心点开始搜索,一共能找到多少个出去的线?
经过仔细考虑,我们不难发现,这里面还有很多的限制条件:
一条线不能经过已经走过的位置。
一条线不能经过已经走过的关于原点对称的位置,这是因为这会对你的另一半分隔产生影响。
如果不考虑这些因素,循环将无限下去,因为它会在里面绕圈圈。
方案拟定:
- 存储:使用二维数组来存储是否走过的标识。计数器count。dir二维数组存储搜索方向。
- 采用dfs进行搜索:
- 确定结束条件:到达边界点,这代表这条线已经画完了,count加一
- 约束条件:不能走到被标记的地方
- 搜索过程中要干的事?没有,本题仅仅是探索有多少条线,中间并不需要干事。
- 深度优先搜索:向四个方向进行搜索
- 标记:本题的标记在进行回溯的时候,应该要消除的,从而免除对其他搜索的影响。这一步也是为什么我没做出来这道题的原因,我们需要对还原有着敏感的认知。
# 计数器
count = 0
# 遍历的方向
dir = [[0, 1], [0, -1], [1, 0], [-1, 0]]
# 所走位置的标识
flag = [[0 for i in range(7)] for j in range(7)]
# 深度优先遍历
def dfs(x, y):
# x, y为搜索的位置
global count
# 约束条件
if flag[x][y] == 1:
return
# 终止条件
if x == 0 or y == 0 or x == 7 or y == 7:
count += 1
return
# 标识
flag[x][y], flag[6 - x][6 - y] = 1, 1
# 进行下一阶段的搜索
for i in range(4):
newx = x + dir[i][0]
newy = y + dir[i][1]
dfs(newx, newy) # 这里不能有return,否则不会进行回溯,也无法向四个方向搜索了
# 还原标识
flag[x][y], flag[6 - x][6 - y] = 0, 0
回顾反思:
- 对于dfs中return的使用,如果要进行回溯。则不能使用。
- 在一个回溯中,我们可以通过还原标识的方法,来消除对其他遍历的影响
- 用树来理解dfs是有帮助的
- 搜索就是搜索,没必要强加一些无用的东西

浙公网安备 33010602011771号