/**
* n皇后问题
*
*/
#include <iostream>
using namespace std;
bool IsLegal (int *c, int n)
{
//位图标志数组,使用 1 ~ n位,最大表示为1 ~ 31,即int型占32位。
//若要求 n > 31 皇后问题,则需修改位图标志数组。
unsigned int bitmap = 1;
//检查全部皇后是否在同一列,若是,则非法。
for (int i = 1; i <= n; ++i){
if ((bitmap >> c[i]) & 1)
return false;
else
bitmap |= 1 << c[i];
}
//检查两两皇后间是否存在在同一对角线上的情况,若是,则非法。
for (int i = 1; i < n; ++i)
for (int j = i + 1; j <= n; ++j)
if (c[i] - c[j] == i - j || c[i] - c[j] == j - i)
return false;
//反之,合法。
return true;
}
void printArray (int *c, int n)
{
for (int i = 1; i <= n; ++i)
cout << c[i] << " ";
cout << endl;
}
//记录解法的数目
static int cnt = 0;
void Queens_Recursion (int *c,int n,int k)
{
for (int i = 1; i <= n; ++i)
{
c[k] = i; //为解答树的第K层生成节点
if (IsLegal(c,n)){ //是最终解,则输出结果
printArray(c,n);
cnt ++;
}
else if (IsLegal(c,k)) //是部分解,则继续穷举
Queens_Recursion(c, n, k + 1); //进入k+1层
}
}
void Queens_iteration (int *c,int n)
{
int k = 1; //解答树从第一层开始
while (k >= 1)
{
while (c[k] < n )
{
c[k]++; //为解答树的第K层生成节点
if (IsLegal(c, n)){ //是最终解,输出结果
cnt ++;
printArray(c, n);
break;
}
else if (IsLegal(c,k)) //是部分解,进入k + 1层
k ++;
}
//回溯
c[k] = 0;
k --;
}
}
int main()
{
const int N = 4; //N 表示n 皇后
int c[20] = {0};
for (int i = 1; i <= N; ++i)
c[i] = 0;
//Queens_iteration(c, N);
Queens_Recursion(c, N, 1);
cout << "Total : " << cnt;
return 0;
}
n 皇后问题的递归和回溯实现 C++
最新推荐文章于 2019-04-17 18:00:02 发布