N皇后问题 --递归及回溯解决方案
2016-09-28 17:34
323 查看
一:介绍
n 皇后等价于要求在一个 n*n 的棋盘上放置 n 个皇后,使得任何两个皇后都不能被放在同一行或同一列或同一斜线上。二:算法设计
对于 n 后问题,我们用 n 元组 x[1:n] 表示它的解。其中 x[i] 表示皇后放在棋盘的第 i 行的第 x[i] 列。由于左上角到右下角的主对角线及其平行线上(斜率为-1),元素2个下标值的差(行号-列号)相等。同理,斜率为+1的斜线上,元素的2个下标值的和(行号+列号)相等。
因此,若两个皇后位置分别为(i, j)和(k,l),且 i - j = k - l 或 i + j = k + l,则说明两个皇后出于同一斜线上。以上两个方程式等价于 i - k = j - l 或 i - k = l - j。
由此可知,只要 |i - k| = |j - l|成立,就表明两个皇后位于同一斜线上。
三:代码实现
#include <iostream> #include <assert.h> using namespace std; const int N_QUEEN = 8; class queen{ friend int n_queen(int num); //设为友元函数 private: //方法为私有,增加安全性 bool place(int k); #ifdef _USE_RECURSION_ void back_track(int t); #else void back_track(); #endif void show()const; private: int num; int *x; long count; }; bool queen::place(int k) //检测能否放置 { for(int i=1; i<k; ++i){ //此处不能等于k,因为是根据之前已经放置好了的皇后判断 if((abs(i-k) == abs(x[i]-x[k])) || (x[i] == x[k])) //第一个条件检测是否在斜线上,第二个检测是否在同一列 return false; } return true; } #ifdef _USE_RECURSION_ void queen::back_track(int t) //递归方法 { if(t > num){ ++count; show(); } for(int i=1; i<=num; ++i){ //下标统一从1开始,便于处理 x[t] = i; if(place(t)) back_track(t+1); } } #else void queen::back_track() { x[1] = 0; //初始化为0是一个技巧 int k = 1; while(k > 0){ x[k] += 1; while((x[k] <= num) && (!place(k))) //如果小于边界,且不能放置,继续向下找 x[k] += 1; if(x[k] <= num){ if(k == num){ //如果到了第八行,成功找到一种情况 ++count; show(); } else{ ++k; x[k] = 0; } } else --k; } } #endif void queen::show()const //打印每种情况的图 { for(int i=1; i<=num; ++i){ for(int j=1; j<=num; ++j){ if(x[i] == j) cout<<'@'<<' '; else cout<<'#'<<' '; } cout<<endl; } cout<<endl; } int n_queen(int num) { queen que; que.num = num; que.count = 0; int *new_base = new int[num+1]; assert(new_base != NULL); que.x = new_base; #ifdef _USE_RECURSION_ que.back_track(1); #else que.back_track(); #endif delete []new_base; return que.count; } int main() { int res = n_queen(N_QUEEN); cout<<res<<endl; return 0; }
部分测试结果如下:
相关文章推荐
- HDOJ/HDU 2553 N皇后问题 回溯加递归
- N皇后问题的递归回溯实现
- 递归与回溯 HDOJ 2553 N皇后问题 1016 Prime Ring Problem
- N皇后问题 递归回溯
- N皇后问题(递归回溯的学习)
- 九度OJ 1254:N皇后问题 (N皇后问题、递归、回溯)
- N皇后问题的非递归回溯和递归回溯
- poj 2533 N皇后问题 -- 递归回溯(打表)
- N皇后问题-回溯与递归-C++实现
- UVa 639 - Don't Get Rooked 类皇后问题 递归回溯
- n皇后问题的递归解决方案
- 【十一】递归与回溯--解决8皇后问题
- 递归回溯问题的四道经典题:N皇后,组合,全排列,二叉树路径和
- 树的递归回溯 n皇后问题
- 蓝桥杯2n皇后问题(简单递归回溯)
- 杭电 2553 N皇后问题 递归回溯 打表 附解题思路
- N皇后问题(回溯递归)
- 回溯法求n皇后问题(递归、非递归及优化)
- N皇后问题(递归+回溯)的C++实现
- 关于递归和回溯的说明以及8皇后问题的递归流程分析