n皇后问题
在n*n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n皇后问题等价于在n*n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。输出可行的棋盘排布,以及可行解的个数。
用回溯法解n皇后问题,以下给出递归回溯与迭代回溯的代码。
/**
* N Queen Problem
*
* 2014-06-25
*/
#include <iostream>
#include <cmath>
using namespace std;
const int MAXN = 12;
int x[MAXN];
int N;
int count;
void PrintQueens()
{
for (int i = 0; i < N; ++i)
{
for (int j = 0; j < N; ++j)
{
if (j == x[i])
break;
else
cout << " ";
}
cout << "Q" << endl;
}
cout << endl;
}
bool CanPlace(int k)
{
for (int i = 0; i < k; ++i)
{
if (x[i] == x[k] || abs(i - k) == abs(x[i] - x[k]))
return false;
}
return true;
}
void RecurBacktrack(int t)
{
if (t == N)
{
PrintQueens();
++count;
}
else
{
for (int i = 0; i < N; ++i)
{
x[t] = i;
if (CanPlace(t))
RecurBacktrack(t + 1);
}
}
}
void IterateBacktrack()
{
int t = 0;
memset(x, -1, sizeof(x));
while (t >= 0)
{
++x[t];
while (!CanPlace(t) && x[t] < N)
++x[t];
if (x[t] < N)
{
if (t == N - 1)
{
PrintQueens();
++count;
}
else
{
++t;
x[t] = -1;
}
}
else
{
--t;
}
}
}
void NQueens()
{
count = 0;
//RecurBacktrack(0);
IterateBacktrack();
cout << count << endl;
}
int main()
{
while (cin >> N)
{
if (N <= MAXN)
NQueens();
}
return 0;
}