递归--N皇后问题


用递归替代多重循环
n皇后问题:输入整数n, 要求n个国际象棋的皇后,摆在n*n的棋盘上,互相不能攻击,输出全部方案。
八皇后问题:八重循环。n皇后,n重循环?


N皇后问题
输入一个正整数N,则程序输出N皇后问题的全部摆法。输出结果里的每一行都代表一种摆法。行里的第i个数字如果是n,就代表第i行的皇后应该放在第n列。
皇后的行、列编号都是从1开始算。
样例输入:
4
样例输出:
2 4 1 3
3 1 4 2

python代码如下:

import sys

#输入的皇后数量
N = 0
#描述第几种方案的值
Num = 0
#用来存放算好的皇后位置,列的位置,最左上角是(1,1),为了自己理解方便,从列表[1]位置开始使用
queenPos = [0] * 100

#格式化输出的皇后棋盘,这里的列表位置从0开始了,所以后面有个减1的比较
def printOutPlace(board):
    global N
    list = board.strip().split(" ")
    for i in  list:
        row = ""
        for j in range(0,N):
            if (j == int(i)-1) : #i这里需要减1,因为原来的棋盘是从第1行,第1列开始计算
                row = row + ""
            else:
                row = row + ""
        print(row.strip())
    #for i, col in enumerate(board):
        #sys.stdout.write('□ ' * col + '■ ' + '□ ' * (len(board) - 1 - col))

#在0~k-1行皇后已经摆好的情况下,摆第k行及其后的皇后
def NQueen(k):
    global N,Num

    outResult = "" #拼接输出的字符串
    #当k=N+1时,说明第N行位置的皇后已经摆好
    if (k == N+1) :
        for t in range(1,N+1):
            outResult = outResult + str(queenPos[t]) + " "
        #print(outResult)

        Num = Num + 1
        print("第%d种方案如下:"%Num)
        printOutPlace(outResult)
    """对传入k这一行的0——N个位置(列)逐一尝试是否符合要求,i变量表示列序号,从1开始
    从第1行、第1列开始计算,以方便理解程序
    整体思想:先对第1行、第1列假设,然后第2行开始递归调用该方法,直至第N行,同时也会第每行每列进行遍历,如果有合适的方案,则输出结果
    接下来对第1行、第2列进行遍历,第2行递归调用……
    …………
    直到第1行、第N列遍历结束
    """
    for i in range(1,N+1):
        #对假设放入的第k行,第i列的棋子与已放置棋子的1至k-1行进行比较是否符合摆放规则,j变量表示行号
        #for j in range(0,k):
        j = 1
        while j < k:
            if (queenPos[j] == i or (abs(queenPos[j] - i) == abs(k - j)) ):
                #出现冲突了
                break
            #如果不冲突,则开始比较下一行
            j += 1
        #如果j与k相等,说明对放入第k行的这一i列与前k-1行都不冲突,符合规则,存储第k行的第i列位置
        #如果j<k,则说明对第k行,第i列与j行冲突了,开始遍历下一列
        if (j == k):
            #与前k行不冲突,存储下第k行,i列的位置放入数组queenPos[]
            queenPos[k] = i
            #这里是算法的核心,需要多理解
            #递归调用,每次完成一行的摆放,从第1行开始,直到N为止
            NQueen(k + 1)
        #return

def main():
    global N
    N = int(input("请输入需要摆放的皇后数量:"))
    #从第1行开始摆放皇后的位置
    NQueen(1)

if __name__=="__main__":
    main()

 

posted @ 2020-02-19 13:55  StudyNLP  阅读(410)  评论(0编辑  收藏  举报