python数据结构学习笔记-2016-11-12-03-八皇后问题

本文介绍了如何使用Python解决八皇后问题,首先通过四皇后问题的解决思路进行讲解,然后探讨了棋盘的设计和递归函数的实现,讨论了如何确保皇后在棋盘上不互相攻击,最终展示了一种用Python实现的棋盘类及其方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        10.5 八皇后问题

        问题描述

        在国际象棋8 × 8的棋盘上放置8个皇后,使得每一个皇后都不能被另一个皇后攻击(皇后可在横竖斜走任意多步)。

        10.5.1 解决四皇后问题

         先将问题规模缩小,我们先来解决四皇后问题。

         在4 × 4的棋盘上,皇后可以在横竖斜三个方向上走任意多步,所以这四个皇后必然处于不同行、不同列。

         我们现在第一列放置皇后,先从(0, 0)开始:


         再在第二列放置第二个皇后,可供选择的地方有(2, 1)和(3, 1)。放在(2, 1)和(3, 1)的结果如下所示:

     

        如果选择(2, 1),则第三列根本就无法再放下一个皇后,从而使得剩下的两个皇后就必须得在第四列,而这又会造成互相攻击,所以不能放在(2, 1),选择(3, 1)。

        第三个皇后就显然只能是放在(1, 2)了,如下所示:


        这样一来,又没有办法在第四列放置最后一个皇后了。所以,只能推到从来,从第一列开始,将第一个皇后放置在(1, 0)。


       之后还是一样的过程。


       四皇后问题有两个解。


       10.5.2 设计解决方案

        这个实现包括两个方面,一个是棋盘,另外一个是寻找解决方法的递归函数

        棋盘定义

  • QueensBorad(n):创建n× n的空棋盘;
  • size():返回棋盘的大小;
  • numQueens():返回当前放置在棋盘的皇后数;
  • unguarded(row, col):返回该位置是否处于当前的所有皇后的攻击 范围;
  • placeQueen(row, col):在该位置上放置皇后;
  • removeQueen(row, col):将该位置上皇后移除;
  • reset():将所有皇后移除,使棋盘返回初始状态;
  • draw():打印棋盘。
        函数的实现如下,它的目的是在一列中,找出皇后放置位置。先确定所有皇后是否都就位了。如果没有,就继续在col列找正确位置,如果与某个位置不处于当前所有皇后的攻击范围内,就将皇后放置在此处,再在下一列中找出正确放置位置,如果都处于当前所有皇后的攻击范围,则说明上一列的皇后放置位置有问题,返回上一列继续寻找皇后的放置位置。
#-*-coding: utf-8-*-

# N皇后问题

def solveNQueens(board, col):
    if board.numQueens() == board.size(): # 确定所有皇后是否都放置好了
        return True
    else:
        # 在这一列找出正确的位置放置皇后
        for row in range(board.size()):
            if board.unguarded(row, col):
                board.placeQueen(row, col):
                if board.solveNQueens(board, col+1):
                    return True
                else:
                    boar.removeQueen(row, col)
        return False # 没有找到正确位置,则会回溯到上一列的皇后放置上来。

          棋盘的实现

          棋盘的实现,可以使用二维数组,也可以使用一维数组。数组的索引就是每一列,而内容则是该列上的每一行,因此,其储存的是皇后的放置位置。

          我们先保证了在竖直方向上,皇后不能攻击。对于新的一列,我们可以查看在水平方向上是否有皇后存在,如果没有就再在左上和左下方向上找。

      

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值