N 皇后问题

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) # 打印八皇后的所有解个数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值