zoukankan      html  css  js  c++  java
  • 八皇后问题

    描述

      将8个皇后放在8*8的棋盘上,要求这8个皇后两两不能在同一水平、垂直或对角线上,求所有放置方法。

    求解

      这是一道经典的递归问题(当然也可以暴力枚举,但不够雅观简洁),8*8的棋盘递归后转变为7*7的棋盘来解决,7*7的棋盘递归后转变为6*6的棋盘来解决,……,但这里的问题是前面的放置会影响后面的放置情况,所以还需要一个记录放置状态的全局变量;后面的放置不成功还会回溯到前面的情况重新放置,所以还要分不同的情况来回溯。

      作为一道递归题,当然只需要解决两部分即可:终止条件和递归核心。

    终止条件

      终止条件只有一个,即已经填完所有的8皇后,显然返回就行了。

    递归核心

      枚举当前行内所有点,如果能成功放置,则放置,并调用下一层递归;如果不能,则自继续枚举该行的下一个点。

      判断放置成功的条件为:

      在水平、垂直线上都比较容易判断,关键是在对角线上的判断为:设两个点为(x1, y1), (x2, y2),则两个点在对角线上应满足(斜率是±1)两条直线方程:x1 + y1 = x2 + y2 (主对角线),x1 - y1 = x2 - y2(副对角线)。

    数据结构

      由于每一行只能放置一个皇后,所以只需要用一个一位数组记录即可,第i行放置了第j列的皇后,记为a[i] = j,这样空间复杂度从O(n²)变为O(n)

    代码

      用Python递归版的代码可以非常简洁:

    num_queen = 8
    count = 0
    queen_col = [0] * num_queen
    
    def recursion(cur_row = 0):
        global num_queen
        global queen_col
        global count
        # stop condition
        if cur_row == num_queen:
            count += 1
            print(queen_col)
            return
        # main recursion process
        for i in range(num_queen):
            queen_col[cur_row] = i 
            flag = True
            # check if the current point is available
            # only check the row before the current row
            for j in range(cur_row):
                x1 =  j
                y1 = queen_col[j]
                x2 = cur_row
                y2 = queen_col[cur_row]
                if y1 == y2 or x1+y1 == x2+y2 or y1-x1 == y2-x2:
                    flag = False
                    break
            if flag:
                recursion(cur_row+1)
    
    recursion()
    print(count)

      输出共92种方法

  • 相关阅读:
    Sign Distance Field 2
    矩阵相乘优化
    Editor GUI 的 Gamma Correction
    GPUSkinning 5
    GPUSkinning 2
    RenderTextureFormat.ShadowMap
    战争迷雾
    Texture2DArray(2)
    软件渲染器 YwSoftRenderer
    将 Unity5.3 的老项目升级到 Unity 2018.3 遇到的些许问题。
  • 原文地址:https://www.cnblogs.com/sbj123456789/p/10519278.html
Copyright © 2011-2022 走看看