N 皇后问题
问题描述:由八皇后问题扩展而来,八皇后问题是指在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
N 皇后即将上述八皇后中的 8 替换为 N 即可,N 个皇后在 NxN 格摆放,不能相互攻击。
Python 解法:
代码如下,使用递归法实现,这个问题划分成 N 个阶段,依次将 N 个棋子放到第一行、第二行、第三行……第N行。在放置的过程中,我们不停地检查当前放法,是否满足要求。如果满足,则跳到下一行继续放置棋子;如果不满足,那就再换一种放法,继续尝试。
# N 皇后类
class Queens:
def __init__(self, count_queens: int):
self.count_queens = count_queens # queens 的个数
self.result = [0]*count_queens # i == row, result[i] == column
self.count_of_ways = 0 # n 皇后问题共有多少种解法
# 计算八皇后问题,将结果写入 self.result
# 输入:row == 0
# 输出: 无
def cal8queens(self, row: int) -> None: # 调用方式, cal8queens(8)
if row == self.count_queens:
self.print_queen()
self.count_of_ways += 1
return
for column in range(self.count_queens):
if self.is_ok(row, column):
self.result[row] = column
self.cal8queens(row + 1)
# 判断 (row, column)的位置是否可以放置皇后
# 输入: row -> int,
# column -> int
# 输出:bool, True:能放置;False: 不能放置
def is_ok(self, row: int, column: int) -> bool:
leftup = column - 1
rightup = column + 1
i = row - 1
while i >= 0:
if self.result[i] == column:
return False
if leftup >= 0 and self.result[i] == leftup:
return False
if rightup < 8 and self.result[i] == rightup:
return False
leftup -= 1
rightup += 1
i -= 1
return True
# 打印 n*n 的 queens 矩阵
# 输入: 无
# 输出: 无
def print_queen(self) -> None:
for row in range(self.count_queens):
for column in range(self.count_queens):
if self.result[row] == column:
print('Q ', end='')
else:
print('* ', end='')
print()
print()
queens = Queens(8) # 新建一个八皇后
queens.cal8queens(0) # 计算八皇后问题的所有解
print(queens.count_of_ways) # 打印八皇后的所有解个数