皇后问题
皇后问题描述如下:在一个n*n的棋盘上放上n个皇后,确保两两皇后之间不在同一列,同一行,同一对角线上,并给出最后满足条件的方法数量。
这其实是一个全排列的问题的变种,棋子的列对应全排列问题中输出序列的index,棋子的行对应全排列问题的每个数。显而易见,每一行放入一个棋子后这行就不能再使用了,就相当于全排列问题中每一个数在排列中用过一遍后就不能再用了。每一行对应的列就相当于全排列问题中每一个数所放入的位置,接着列+1,进行递归。这样的排列结果一定是行列交错的。
简而言之就是,把行抽象成数,把列作为输出数组,对行进行全排列,放入列中输出。
在递归过程中检查如果两个棋子之间行差等于列差,那么说明在对角线上,提前回溯。
以下给出代码:
#include<iostream>
#include<math.h>
using namespace std;
bool queen(bool* &hash, int* &out, int length, int index, int &sum)
{
if (index > length)
{
sum++;
return true;
}
else
{
for (int i = 1;i <= length;i++)
{
bool bz = true;
for (int j = 1;j < index;j++)
{
if (index - j == abs(i - out[j]))
bz = false;
}
if (!hash[i]&&bz)
{
hash[i] = true;
out[index] = i;
queen(hash, out, length, index + 1, sum);
hash[i] = false;
}
}
}
}
int main(void)
{
int num;
cin >> num;
int sum = 0;
bool* hash = new bool[num + 1]{ false };
int* out = new int[num + 1];
queen(hash, out, num, 1, sum);
cout << sum << endl;
return 0;
}