N皇后问题是指在一个N*N的国际象棋棋盘上,有N个棋子,这N个棋子均不在同一行,同一列,同一对角线上,请问一共有几种排列方式?
因为每列都要有棋子,所以只要把每一列的棋子所在的行数排下来就行了,比如第一列到第五列棋子所在的行数依次是24135,然后只要查看每种方法是否满足要求就行了。
void generate(int index)//index是所在的列数
{
bool flag = true;//假设现在这种排列是正确的
if (index == n + 1)//如果排列已经完成,就是列数已经循环到n+1
{
for (int i = 1; i <= n; i++)//
{
for (int j = i + 1; j <= n; j++)
{
if (abs(i - j) == abs(P[i] - P[j]))//是否满足不在同一对角线
{
flag = false;
}
}
}
if (flag)//如果不在同一对角线,那么满足
num++;
return;
}
for (int i = 1; i <= n; i++)//当还没装满一种排列的时候继续创造排列方式
{
if (hashTable[i] == false)
{
P[index] = i;//在每一列中赋值一个行数
hashTable[i] = true;
generate(index + 1);
hashTable[i] = false;
}
}
}
下面给出总的代码
#include<iostream>
#include<cmath>
using namespace std;
int n;
const int maxn = 20;
int num = 0;
int P[maxn], hashTable[maxn] = { false };
void generate(int index)
{
bool flag = true;
if (index == n + 1)
{
for (int i = 1; i <= n; i++)
{
for (int j = i + 1; j <= n; j++)
{
if (abs(i - j) == abs(P[i] - P[j]))
{
flag = false;
}
}
}
if (flag)
num++;
return;
}
for (int i = 1; i <= n; i++)
{
if (hashTable[i] == false)
{
P[index] = i;
hashTable[i] = true;
generate(index + 1);
hashTable[i] = false;
}
}
}
int main()
{
cin >> n;
generate(1);//从第一列开始
cout << num << endl;
system("pause");
return 0;
}