N-Queen Problem
2015-10-23 00:34
302 查看
Please indicate the source if you want to reprint: http://blog.csdn.net/gaoxiangnumber1.
使用回溯算法解决N皇后问题.
问题描述:
棋盘为N*N的,在该棋盘上放置N个皇后,使得任意两个皇后不在同一行或者同一列或者同一对角线(主对角线和副对角线)。
解题思路:
必定使得棋盘的每一行每一列均存在且只存在一个皇后,所以遍历所有的行,对每一行,遍历所有的列,使用判断条件排除。
直接用visit[][]这个二维数组来判断当前尝试放的位置所在的列(visit[0][column])、对角线1(visit[1][row+column])、对角线2(visit[2][row-column+queen_number])是否已经放了皇后(放了为1,没放为0)。如果没放,那么放上(position[100]用来存储路径,如果不需要打印路径,则不需要该数组);如果放了尝试下一个位置。
注意:BackTrack(row+1)语句执行完以后,表明对于当前的位置已经求得了结果,所以向上一层程序返回的时候,一定将状态改回:“没被访问”。一般的:如果在回溯法中修改了辅助的全局变量,则一定要及时将他们恢复原状。若函数有多个出口,则需要在每个出口的地方恢复被修改的值。
NQueen.cc
Please indicate the source if you want to reprint: http://blog.csdn.net/gaoxiangnumber1.
使用回溯算法解决N皇后问题.
问题描述:
棋盘为N*N的,在该棋盘上放置N个皇后,使得任意两个皇后不在同一行或者同一列或者同一对角线(主对角线和副对角线)。
解题思路:
必定使得棋盘的每一行每一列均存在且只存在一个皇后,所以遍历所有的行,对每一行,遍历所有的列,使用判断条件排除。
直接用visit[][]这个二维数组来判断当前尝试放的位置所在的列(visit[0][column])、对角线1(visit[1][row+column])、对角线2(visit[2][row-column+queen_number])是否已经放了皇后(放了为1,没放为0)。如果没放,那么放上(position[100]用来存储路径,如果不需要打印路径,则不需要该数组);如果放了尝试下一个位置。
注意:BackTrack(row+1)语句执行完以后,表明对于当前的位置已经求得了结果,所以向上一层程序返回的时候,一定将状态改回:“没被访问”。一般的:如果在回溯法中修改了辅助的全局变量,则一定要及时将他们恢复原状。若函数有多个出口,则需要在每个出口的地方恢复被修改的值。
NQueen.cc
#include<iostream> #include<cstring> // to use memset using namespace std; int queen_number, solution_number; // visit[0][column] = 0 if there is no queen in this column; otherwise = 1; // visit[1][row + column] and visit[2][row - column + queen_number] are for 2 // kinds of diagonals(/ and \), = 0 if no queen on this line; otherwise = 1. // row + column & row - column + queen_number can be easily calculated // by formula: y = k*x + b, which y(row), k(1 or -1), x(column) and b is a constant. // Note: row - column can be negative, so we add queen_number to guarantee that // the index is nonnegative. int visit[3][100]; // position[row] = column: queen in row "row" should be placed in column "column" // this array is not essential if you don't print solutions. int position[100]; void Output(); void BackTrack(int row); int main() { while(1) { memset(visit, 0, sizeof(visit)); // set all numbers in visit to 0 solution_number = 0; cout << "Please input queen_number:\n"; cin >> queen_number; BackTrack(0); // start place queens from [0]row cout << "Total solutions number is " << solution_number << endl; } } void BackTrack(int row) { if(row == queen_number) // we should place queens in [0, queen_number - 1]row, so row equals to queen_number // indicates we have placed all queens, so get a solution and stop backtracking. { solution_number++; Output(); } else { // for current row "row", check each column whether can place queen by "visit" // and if can, change according element in "visit" and continue placing queen // in next row "row + 1". for(int column = 0; column < queen_number; column++) { if(visit[0][column] == 0 && visit[1][row + column] == 0 && visit[2][row - column + queen_number] == 0) { position[row] = column; visit[0][column] = visit[1][row + column] = visit[2][row - column + queen_number] = 1; BackTrack(row + 1); // after backtrack return, we must retrieve "visit" because we will place queen // in another column for current row by "column++". visit[0][column] = visit[1][row + column] = visit[2][row - column + queen_number] = 0; } } } } void Output() { for(int row = 0; row < queen_number; row++) { for(int column = 0; column < queen_number; column++) { // 1 stand for has queen; otherwise 0 cout << ((position[row] == column) ? "1 " : "0 "); } cout << endl; } cout << endl; } /* 1: 1 2: 0 3: 0 4: 2 5: 10 6: 4 7: 40 8: 92 9: 352 10: 724 */
Please indicate the source if you want to reprint: http://blog.csdn.net/gaoxiangnumber1.
相关文章推荐
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析
- C++实现汉诺塔算法经典实例
- PHP实现克鲁斯卡尔算法实例解析
- C#获取关键字附近文字算法实例