递归--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()