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

原文地址:https://www.cnblogs.com/an-wl/p/12331029.html

时间: 2024-10-04 02:43:00

递归--N皇后问题的相关文章

15、蛤蟆的数据结构笔记之十五栈的应用之栈与递归之八皇后问题

15.蛤蟆的数据结构笔记之十五栈的应用之栈与递归之八皇后问题 本篇名言:"人的一生应当这样度过:当回忆往事的时候,他不致于因为虚度年华而痛悔,也不致于因为过去的碌碌无为而羞愧:在临死的时候,他能够说:"我的整个生命和全部精力,都已经献给世界上最壮丽的事业--为人类的解放而斗争." 继续递归问题,本次是经典的八皇后问题: 欢迎转载,转载请标明出处: 1.  八皇后问题 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出

递归 八皇后

递归 八皇后 题意 > 棋子不能在同一行,同一列,以及同一对角线. > 输出所有符合要求的情况. 步骤:用计数器统计次数,按列写出全排列,再枚举任意两个棋子,如果不符合条件,则计数器不变. #include <cstdio> #include <algorithm> const int maxn = 100; int n, p[maxn], hashTable[maxn] = {false}; int count = 0; void generateP(int inde

递归---n皇后

---恢复内容开始--- #include "stdafx.h" #include <iostream> #include <fstream> //文件流 #include <iomanip> #include <cstdlib> using namespace std; void queenSolve(int rowCurrent, int n, int *&queenlist, int &count, ofstream

递归 八皇后复习

#include <bits/stdc++.h> using namespace std; #define maxn 20 int map[maxn][maxn]; bool vis[3][2*maxn]; int ans, C[maxn]; int N; int tot; void print() { printf("第%d种摆放方法: ", ++tot); for(int i=0; i<N; i++) cout<<C[i]+1<<"

递归8皇后,10皇后以上栈就爆了

#include <stdio.h> #define N 9 int q[N] = {0}; int cnt = 0; void print_q() { int i; for (i=0; i<N; i++) printf("%d ", q[i]); printf("\n"); return; } int can_put(int m, int n) { int i,j; //row is ok //colume for (i=0; i<m; i

8皇后及其普及(N)——小试牛刀(1)

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻 击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 高斯认为有76种方案.1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果.计算机发明后,有多种计算机语言可以解决此问题.——————————摘自<度娘百科>       八皇后问题是回溯与搜索的一个很典型的例子.算法

Arithmetic_Thinking_Dateback

回溯法--是一个很常见的算法求解方式,它主要是把问题所有的解都按照解空间树都列出来,然后只要不符合条件的立马"剪枝",就是回到前面的相应的父节点,将它去除,这种方式有点像父节点生出一些子节点,若是这些子节点都不争气,没办法满足需求,就会将父节点"判刑",因为他也是他父节点中不满足条件的一个子节点,直到根节点,然后又换一个根节点,再来一遍,这种方式就可以用递归来实现 上代码吧,这次解决的是一个比较常见的问题,N皇后问题,我在这里先展示4皇后的解法,更多的思想是一样的

回溯算法的实现

回溯算法: 从一条路往前走,能进则进,不能进则退回来,换一条路再试.(以深度优先方式搜索) 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择. 使用回溯法求任一个解时,只要搜索到问题的一个解就可以结束 用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被搜索遍才结束. 回溯法的实现方法有两种:递归和递推(也称迭代).一般来说,一个问题两种方法都可以实现,只是在算法效率和设计复杂度上有区别. 递归思路简

8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化

上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来探讨一下非递归方案 实验结果令人还是有些失望,原来非递归方案的性能并不比递归方案性能高 代码如下: package com.newflypig.eightqueen; import java.util.Date; /** * 使用循环控制来实现回溯,解决N皇后 * @author [email pr