研究了一下午的八皇后算法,可算是搞明白了,为了避免以后忘记,还是写个博客吧!可能会跟其他文章有相似之处,最终还是希望能好好学习算法,都是经过自己思考后亲自写的代码,虽然过程比较艰难,我写了很多注释。

目录

一、问题描述

二、解题思路

三、总体步骤

四、代码实现

寻找函数编写:

打印输出函数:

主调用函数:

测试结果:

个人心得


一、问题描述

有八个皇后,如何在8*8的棋盘上放置8个皇后,使得任意两个皇后都不在同一条横线、纵线或斜线上

二、解题思路

8皇后 python 递归 python八皇后问题递归算法_python

三、总体步骤

8皇后 python 递归 python八皇后问题递归算法_调用函数_02

四、代码实现

寻找函数编写:

# row表示递归到第几行,初始从第0行开始,n表示棋盘规模n行n列,这个始终不变
def search(row, n):
    global count   # 声明全局变量
    for col in range(n):
        # 表示在同一条上对角线上:行号加列号相同;表示在同一条下对角线上:行号减列号相同,为了避免索引出现复数,用row-col+n-1
        if flag_y[col] == 0 and line_up[row+col] == 0 and line_do[row-col+n-1] == 0:
            # 如果该点所在的行、列、对角线都没有被标记,则该点可以占领
            place[row] = col    # 表示第row行的第col列被占领:例如place[0] = 1 表示第1行的第2个点被占领
            flag_y[col] = 1   # 占领后将该点所在 的列 标记为1
            line_up[row+col] = 1   # 该点所在的 上对角线 被标记为1
            line_do[row-col+n-1] = 1   # 该点所在的 下对角线 也标记为1
            if row < n-1:
                # 如果该行不是棋盘的最后一行,则继续递归调用,寻找下一行的占领点,行数row+1
                search(row+1, n)
            else:
                # 已经到了最后一行,则证明找到一组可行的八皇后摆放点
                count += 1
                printf(place, n)  # 将这个解的形状打印输出
                print(place)  # 输出该结果

            # 到这里已经找到一个解,在寻找下一个解之前,要将棋盘的标记清空
            flag_y[col] = 0
            line_up[row + col] = 0
            line_do[row-col+n-1] = 0

打印输出函数:

# 输出棋盘样式
def printf(pos, n):
    # 遍历n*n的棋盘格子
    for i in range(n):
        for j in range(n):
            if pos[i] == j:
                # 如果第i行的皇后放在了第j列上,就输出*表示皇后的位置
                print("*", end=" ")
            else:
                print('0', end=" ")
        print()

主调用函数:

if __name__ == '__main__':
    n = int(input("请输入棋盘的规模n\n"))  # 代表n*n棋盘
    count = 0  # 存储可行解的个数
    # 表示标记,初始标记都为0
    place = [0 for i in range(n)]  # 记录第几行的皇后放在第几列上
    flag_y = [0 for i in range(n)]  # 表示第i列是否被标记(占领)
    line_up = [0 for i in range(2 * n - 1)]  # 上对角线是否被标记,总共有2n-1条上对角线
    line_do = [0 for i in range(2 * n - 1)]  # 表示下对角线是否被标记,总共有2n-1条下对角线
    search(0, n)    # 从第0行开始寻找
    print("总共有{}种结果".format(count))

测试结果:

8皇后 python 递归 python八皇后问题递归算法_python_03

8皇后 python 递归 python八皇后问题递归算法_八皇后_04

8皇后 python 递归 python八皇后问题递归算法_调用函数_05

测试结果是正确的,如果是4*4的棋盘,总共有两个解;如果是8*8的棋盘,总共有92个解。

个人心得

理解算法一定不能急,每一步都要搞懂,网上关于这个题有很多种算法,我觉得只要抓住一种吃透就好。还有最近也看了很多博主对算法学习的看法,感觉自己收获了很多,最大的感触就是:语言并不是学习算法的障碍,用python写并不比用C、C++的人差,语言只是一个工具罢了,我们应该慢慢打破语言之间的壁垒,所以首先C、C++的代码也要看得懂,毕竟很多经典算法都是用这些编写的,算法核心思想都是一样的,参加比赛选一个自己喜欢的编程语言就好。