NQueens 与 递归,回溯
来源:互联网 发布:系统性能优化 编辑:程序博客网 时间:2024/05/16 17:19
NQueens 问题描述:
规则:两个皇后 在同一行,同一列,同一斜线上都会打架 (即皇后不能放在同一行,同一列,同一斜线上)上图是 8*8 棋盘放置8个皇后的一种方法示意图。现有 n*n 棋盘,放 n 个皇后,提供算法,求一共有多少种不同的放置皇后的方法。
思路:(回阙法)
1)第一步有 n*n 个位置可以下,后面每一步,需要遍历棋盘,根据规则检验,确定位置。因此需要遍历棋盘。
2)每下一步前,都需要根据规则检验。这里可以用集合记录已放置皇后的位置(col,row),所在斜线(row+col, row-col)信息。
3)如果遍历完一次不满足条件,则需要将当前皇后信息都移出集合,进行下一次遍历试探。即回溯思想。
4)如果能顺利遍历完最后一行,最后一列,则解法count++;
下面是C#代码示例:
public class Solution { ICollection<int> colSet = new HashSet<int>(); //column ICollection<int> diaSet1 = new HashSet<int>(); //diagonal ICollection<int> diaSet2 = new HashSet<int>(); public int TotalNQueens(int n) { int count = TotalQueensHelper(0,0,n); return count; } private int TotalQueensHelper(int row, int count, int n){ for(int col =0; col<n; col++){ if(colSet.Contains(col)) continue; int dia1 = row + col; if(diaSet1.Contains(dia1)) continue; int dia2 = row - col; if(diaSet2.Contains(dia2)) continue; if(row == n-1){ //顺利遍历完 count ++; }else{ colSet.Add(col); diaSet1.Add(dia1); diaSet2.Add(dia2); count = TotalQueensHelper(row+1,count,n); // colSet.Remove(col); diaSet1.Remove(dia1); diaSet2.Remove(dia2); } } return count; }}
一些关键点:
1) 二维数组中,同一斜线的数特性:row+col('/'该趋势斜线),row-col('\'该趋势斜线) 为同一个数2) 函数调用,系统的处理工作: 当一个函数的运行期间调用另一个函数的时候,在运行被调用函数之前,系统都会先完成三件事: (1)将所有的实在参数、返回地址等信息传递给被调用的函数保存; (2)为被调用的局部变量分配存储区; (3)将控制转移到被调用的函数的入口。 而从被调用函数返回调用函数之前,系统也应完成三件事: (1)保存被调用函数的计算结果; (2)释放被调用函数的数据区; (3)依照被调用函数保存的返回地址将控制转移到调用函数上。 当有多个函数构成嵌套语句时,按照,“后调用先返回”的原则,上述的函数之间的信息传递和控制的转移必须通过“栈”来实现,即系统将整个程序运行时间所需的数据安排在一个栈中,每当调用一个函数时,就为它在栈顶分配一个存储区,每当一个函数退出时,就释放它的存储空间,则当前正在运行的函数的数据区必在栈顶。3) 递归是函数调用的一种特殊调用。
private int TotalQueensHelper(int row, int count, int n){ for(int col =0; col<n; col++){ if(colSet.Contains(col)) continue; int dia1 = row + col; if(diaSet1.Contains(dia1)) continue; int dia2 = row - col; if(diaSet2.Contains(dia2)) continue; if(row == n-1){ //顺利遍历完 count ++; }else{ colSet.Add(col); diaSet1.Add(dia1); diaSet2.Add(dia2); count = TotalQueensHelper(row+1,count,n); // colSet.Remove(col); diaSet1.Remove(dia1); diaSet2.Remove(dia2); } } return count; }
这里需要注意的是:
被调用函数,运行return后,是返回到调用函数继续执行。这里跟循环里的 return 退出循环不一样。
递归里的 return 是返回到上一层调用。
这里的 count = TotalQueensHelper(row+1,count,n); 是局部变量采用连续传递计数的,还可以采用全局变量。
0 0
- NQueens 与 递归,回溯
- 递归与回溯
- 递归与回溯算法
- 回溯与递归
- 递归与回溯
- 递归与试探回溯(2) 试探回溯法
- 回溯与递归算法的区别
- 回溯与递归算法的区别
- 递归与回溯:八皇后问题
- 数独算法-递归与回溯
- 数据结构与算法练习-回溯、递归
- 递归回溯
- 递归回溯
- 递归回溯
- 递归回溯
- 关于回溯算法的递归与非递归解法
- 递归与试探回溯(1) 简单递归分析
- NQueens II
- ethtool测定Linux服务器上网卡硬件与网口的对应关系
- 在 ios 与 android 同时支持js功能,即web与app的交互功能的实现
- ACM——输入输出外挂
- PET重建技术 MLEM迭代法(C++)(一) 原理及成像
- listView滚动高度
- NQueens 与 递归,回溯
- hdu3065 病毒侵袭持续中(AC自动机)
- xss漏洞修复
- win7 没有休眠按钮
- 不定义JQuery插件,不要说会JQuery
- IDEA快捷键
- C++强大的背后
- STF开源框架之minicap工具
- 流感传染(C程序设计进阶第2周)