您的位置:首页 > 产品设计 > UI/UE

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

#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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法