3.2 回溯法—N皇后问题
1. 问题描述
在n×nn\times nn×n的棋盘上摆放nnn个皇后,使任意两个皇后都不能处于同一行、同一列或同一斜线上
2. 问题分析
下以求解4皇后问题为例,分析4皇后问题的排列树以及回溯过程:
搜索及回溯过程:
解空间树:
3. 算法设计
1. 算法思想
①用数组x[]存放皇后的位置,x[k]表示第k个皇后放置的位置
②先在第一行放置第1个皇后,然后依2、3、…、n的次序放置其他皇后,当第n个皇后放置好后产生一个可行解(为得到所有解,还需要继续试探第n个皇后的下一个位置)
③试探每个皇后的位置都是从第1列开始的
④当第k个皇后试探了所有列都不能放置时,则回溯到第k-1个皇后,试探第k-1个皇后的下一个位置:如果第k-1个皇后的列号x[k-1]<n,则将其移到下一列,继续试探;否则,再回溯到第k-2个皇后,依次类推
⑤放置第k个皇后应与前面已经放置的k-1个皇后不发生冲突
⑥若第1个皇后的所有位置回溯完毕,则算法结束
2. 代码实现
#include<stdio.h>
#include<math.h>
#include<string>
//考察皇后k放置在x[k]列是否发生冲突
int Place(int k, int x[]) { for (int i = 1; i < k; i++)/* x[k] == x[i]:是否在同列Math.abs(k - i) == Math.abs(x[k] - x[i]):是否在同一斜线*/if (x[k] == x[i] || fabs(k - i) == fabs(x[k] - x[i]))return 1; //冲突则返回1return 0;
}
/*求解n皇后问题
*/
//非递归算法
void Queens(int n, int x[]) { int i = 1; //i表示当前行,也表示放置第i个皇后x[i] = 0; //x[i]是当前列,每个新考虑的皇后初始位置置为0列while (i >= 1) { //尚未回溯到头,循环x[i]++; //原位置后移动一列while (x[i] <= n && Place(i, x) == 1) //发生冲突,试探下一个位置(i, x[i])x[i]++;if (x[i] <= n) { //为第i个皇后找到了一个合适位置(i, x[i])if (i == n) { //若放置了所有皇后,输出一个解for (int k = 1; k <= n; k++)printf("%d ", x[k]);printf("\n");}else { //若皇后没有放置完i++; //转向下一行,即开始下一个新皇后的放置x[i] = 0; //每个新考虑的皇后初始位置置为0列}}else i--; //若第i个皇后找不到合适的位置,则回溯到上一个皇后}
}//递归算法
void Queens(int i, int x[], int n){if(i > n){for (int k = 1; k <= n; k++) //n个皇后都放置好,输出printf("%d ", x[k]);printf("\n");
}elsefor(int j = 1; j <= n; j++){ //每层均有n种放法x[i] = j; //放置皇后t在第i列即x[t]if(Place(i, x) == 0) //不冲突,考察皇后t放置在x[t]列是否发生冲突Queens(i+1, x, n); //继续递归放置下一个皇后}
}void main() {int n;printf("请输入皇后个数:");scanf_s("%d", &n);int *x = (int *)malloc(sizeof(int)*(n+1));//非递归调用Queens(n, x);//递归调用//Queens(1, x, n);
}
4. 复杂度分析
该算法中每个皇后都要试探n列,共n个皇后,其解空间是一棵子集树,每个结点可能有n棵子树,对应的算法时间复杂度为O(nn)O(n^n)O(nn)
利用显示约束排除两个皇后在同一行或同一列的方法,解空间树就是一棵排列树,因此共有n!n!n!个叶子结点,所以算法的时间复杂度可以降为O(n!)O(n!)O(n!)
3.2 回溯法—N皇后问题相关推荐
- 一、试探回溯法(N皇后问题)
一.试探回溯法概念 在介绍试探回溯法的概念之前,先简要介绍一个简短的古希腊神话故事,邪恶的半人半牛藏身于一个复杂的迷宫,很难找到它并杀死它,就是能成功杀死它怎么回来也是个难事.不过,在公主阿里阿德涅 ...
- 回溯法——N皇后问题
N皇后问题即给一个n*n方格,将n个皇后放进去,要求皇后不能出现在同一列,同一行,也不能出现在对角线上,换句话说,只有折线才可能连接两个皇后.我们拿四皇后来举例: 如图1,第三行的皇后放第一个各格子的 ...
- c支限界算法语言n皇后问题分,算法(八)-回溯法-N皇后问题
问题描述: 算法思想: 代码实现: #include using namespace std; class Queen { friend int nQueen(int);//求解八皇后 private ...
- 算法设计与分析——回溯法——n皇后问题
一.什么是N皇后问题? 在n×n格的棋盘上放置彼此不受攻击的n个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后 ...
- 回溯法 n皇后 python 解法一
输出所有解 global N N = 4def printSolution(board):for i in range(N):for j in range(N):print(board[i][j], ...
- 【Java -- 算法】分治算法、动态规划、回溯法、贪心算法
前言 一句话理解四种算法思想 分治:分而治之,先解决子问题,再将子问题的解合并求出原问题. 贪心:一条路走到黑,选择当下局部最优的路线,没有后悔药. 回溯:一条路走到黑,手握后悔药,可以无数次重来.( ...
- 八皇后问题 回溯法hdu2553
N皇后问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...
- 七十八、 回溯法解决八皇后问题
@Author:Runsen 八皇后问题 八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后. 来自百度百科,皇后的走法是可 ...
- HDU2553 N皇后 回溯法+打表
点击打开链接 N皇后问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
最新文章
- 网络推广外包中如何让网络推广外包专员充分运用网站的市场价值?
- 10.切片slice.rs
- Jq获取同一名称单选框(radio)被选中的值
- lean软件Android有吗,leanchat-android
- 33.卷1(套接字联网API)---调试技术
- (数据结构)约瑟夫环问题——C语言实现
- wps怎么导入access_WPS Access 2013_access 2013下载-下载之家
- 后羿 11 ‖ 洛神
- 此页面上的脚本造成Web浏览器运行速度减慢。如果继续运行,您的计算机将可能停止响应。
- python风变编程和扇贝编程_想学习phython ,纠结是扇贝编程还是风变编程?
- LED驱动程序的编写
- 十九个国内外主流的三维GIS软件
- python如何画神经网络特征图
- 为文字添加下划线和中划线
- 数学基础task04 一元函数微分学的几何应用
- java如何实现系统定位_如何快速定位到系统中某一功能的具体实现
- 【09】FreeRTOS的时间片调度
- 九招最有效防电脑辐射方法
- 走向单体地狱(一):Maven详解
- L1-044 稳赢(15分) java
热门文章
- U盘插电脑有提示音但不显示盘符怎么办?
- [2021年最新]国产时序性数据TDenige入门
- 基于MODnet无绿幕抠图
- Linux查看硬件信息以及驱动设备的命令
- 12月17日云栖精选夜读 | 用PrettyPrinter,让Python输出更漂亮,你值得拥有...
- 一个html基本写法,HTML5教程:HTML5的基础写法
- 鸿海集团董事长郭台铭:数字经济是中国制造2025的根基
- TIL:创建Java线程的两种方法
- 史上最小白之RNN详解
- 从万达百货到家乐福中国,苏宁如何快速消化“大块头”?