N皇后问题
来源:互联网 发布:网络推广需要多少钱 编辑:程序博客网 时间:2024/04/30 05:04
一、问题描述:
在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不妨在同一行或同一列或同一斜线上。
输入:
给定棋盘的大小n (n ≤ 13) 大于11后,可能会超时。建议数字大额时候,打表记录下来。
输出:
输出有多少种放置方法。
二、解题思路:
要解决N皇后问题,其实就是要解决好怎么放置这n个皇后,每一个皇后与前面的所有皇后不能在同一行、同一列、同一对角线,在这里我们可以以行优先,就是说皇后的行号按顺序递增,只考虑第i个皇后放置在第i行的哪一列,所以在放置第i个皇后的时候,可以从第1列判断起,如果可以放置在第1个位置,则跳到下一行放置下一个皇后。如果不能,则跳到下一列...直到最后一列,如果最后一列也不能放置,则说明此时放置方法出错,则回到上一个皇后向之前放置的下一列重新放置。此即是回溯法的精髓所在。当第n个皇后放置成功后,即得到一个可行解,此时再回到上一个皇后重新放置寻找下一个可行解...如此后,即可找出一个n皇后问题的所有可行解。
三、复杂度分析:
关于N皇后问题的复杂度问题可以说是众说纷纭了,自己也改变过好几次,刚开始以为棋盘是n行n列,所以理所当然应该是n^2,后来发现在每列选择可否放置的比较上又做了一次循环,所以应该是n^3,但想了很久,发现判断可否放置的时候不是每次都循环到n,它是根据皇后i的取值而变化的,所以复杂度应该是1/3 n^3左右,即是小于n^3的。
四、测试代码:
在这里我写了两个实现方法,一个是递归回溯,一个是迭代回溯,思路都一样,只是形式不同罢了。
递归回溯:
迭代回溯:
迭代回溯的注释因为和递归回溯差不多,所以就不再附注了。在这里我们可以看到,递归回溯非常简单,结构很清晰,但它有一个潜在的问题存在,即当随着变量n的增大,递归法的复杂度也将成几何级增长,也有可能会出现重复的情况,所以我们在解决问题时,如果能用迭代法解决,最好还是不要用递归法,除非你已经对这个递归了如指掌了。
通过这个N皇后问题,我想大概已经把回溯法讲得很清楚了吧,回溯法得到的解展开就是一个树,很多方法都是可以通过回溯法来解决的,效率很高,但如果基数过大的话,回溯法就显得不是那么适用了,这也是回溯法的弱势吧。比如说这个N皇后问题,好像当n>60的时候,回溯法就不能完全地解决问题了,这时可以考虑用概率算法来解决,它可以解决很大的基数,只不过结果不是很精确而已。所以我们在面对一个问题时,具体是使用什么算法还是要结合实际情况来考虑的,目的都是更方便、更准确地解决问题
输入:
输出:
二、解题思路:
三、复杂度分析:
四、测试代码:
递归回溯:
C代码
-
- #include<stdio.h>
- #define
N 15 -
- int
n; //皇后个数 - int
sum //可行解个数= 0; - int
x[N]; //皇后放置的列数 -
-
- int
place( intk) - {
-
i; -
-
|| x[k] == x[i]) -
0; -
1; - }
-
-
- int
queen( intt) - {
-
&& //当放置的皇后超过n时,可行解个数加1,此时n必须大于0n>0) -
sum++; -
-
i=1;i<=n;i++) -
{ -
x[t] = i; -
//如果可以放在某一位置,则继续放下一皇后 -
queen(t+1); -
} -
sum; - }
-
- int
main() - {
-
t; -
scanf( -
t = queen(1); -
== //如果n=0,则可行解个数为0,这种情况一定不要忽略0) -
t = 0; -
printf( -
0; - }
迭代回溯:
C代码
-
- #include<stdio.h>
- #define
N 15 -
- int
n; - int
sum = 0; - int
x[N]; -
- int
place( intk) - {
-
i; -
-
|| x[k] == x[i]) -
0; -
1; - }
-
- int
queen() - {
-
x[1] = 0; -
t=1; -
-
{ -
x[t]+=1; -
&& !place(t)) -
x[t]++; -
-
== n) -
sum++; -
-
x[++t] = 0; -
-
t--; -
} -
sum; - }
-
- int
main() - {
-
t; -
scanf( -
t = queen(); -
printf( -
0; - }
- N*N皇后问题
- 八皇后 n皇后 问题
- 八皇后N皇后问题
- N皇后问题
- n皇后问题
- N皇后问题
- N 皇后问题
- N皇后问题
- N皇后问题算法
- N 皇后问题
- N皇后问题
- N皇后问题
- n皇后问题
- N皇后问题
- N皇后问题优化
- N皇后问题
- n皇后问题
- N皇后问题
- linux串口通信参数宏详解实例
- 二分查找
- NSIS:.NET Runtime Library检测和本地安装
- Installing apache on RHEL
- Some jar(v4 support, ActionBarSherlock and etc.) import error in Android Studio
- N皇后问题
- 从zero起☞Python
- VS2010中的调试技巧
- 整数的二进制表示中1的个数(28)
- vs2010:fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "StdAfx.h"”?
- C++空类有哪些成员函数
- sqlite的使用
- Set的使用
- HBase的一些理解