原题
有一个 的国际象棋棋盘( 行 列的方格图),请在棋盘中摆放 个受伤的国际象棋皇后,要求:
- 任何两个皇后不在同一行。
- 任何两个皇后不在同一列。
- 如果两个皇后在同一条 45 度角的斜线上,这两个皇后之间行号的差值至少为 3 。
请问一共有多少种摆放方案。
分析
本题考查搜索,一般这种涉及“矩阵”的搜索使用递归方法会更直观、简便。在一个n*n的棋盘上放置“皇后”象棋,首先考虑第一个条件:同一行的所有格子只能摆放在其中一个摆放棋子,所以可以一行一行的放,即先按行进行放置方案的“搜索”。“搜索”的实现如下:
- 首先在第i行中选择其中的第j个格子放置一个象棋(i,j=0,1,2,...,n-1)
- 然后在第i+1行放置象棋,准备放在第j_new个格子(j_new=0,1,2,...,n-1),放置之前,需要判断这个格子是否可以放置
- 判断当前格子是否可以放置的依据:是否满足题意中的后两个条件
- 当i = n-1,即最后一行已经放置象棋,此时整个棋盘的象棋的摆放即为所“搜索”的一种方案
源码
n = int(input())
An_l = [ [0]*n for _ in range(n)] #表示棋盘的n*n的矩阵
count = 0
def is_can_put(i,j):
'''判断(i,j)位置是否可以摆放皇后'''
# 同一条 45 度角的斜线上,这两个皇后之间行号的差值至少为 3
for ii,jj in [ (i-1,j-1),(i-2,j-2),(i-1,j+1),(i-2,j+2) ]:
if ii >=0 and ii < n and jj >= 0 and jj < n:
if An_l[ii][jj] == 1:
return False
# 同一列不能放置
for ii in range(i):
if An_l[ii][j] == 1:
return False
return True
def put(i,j):
global count
if i == n-1: # 最后一行已放置
# print(An_l)
count += 1
return
i += 1
for j in range(n):
if is_can_put(i,j):
An_l[i][j] = 1
put(i,j)
An_l[i][j] = 0
for j in range(n):
An_l[0][j] = 1 # 第0行的第j列放置皇后
put(0,j)
An_l[0][j] = 0 # 拿掉皇后,回溯
print(count)
上一篇:蓝桥杯备战日志(Python)19-阅兵方阵&删除字符-(平方和频次统计&字符串字典序)