参数:
n:表示棋盘大小nxn,也表示皇后的个数
x[i]:存放第i个皇后所在列数
sum:可行解总数
注意:
任意两个皇后不能再同一斜线上,是一个隐约束,应将其转为显约束。
对于nxn方阵上的同一斜线,分为两种:主对角线及平行线(即斜率为-1的直线),副对角线及平行线(即斜率为+1的直线)。其中斜率为-1的直线,行号-列号值必定相等,斜率为1的直线,行号+列号必定相等。因此,若2个皇后的位置分别为(i,j)和(k,l),且i-j=k-l或i+j=k+l,则说明2个皇后在同一斜线上。以上两个方程分别等价于k-i=l-j和k-i=j-i,所以,只要|k-i|=|j-l|,就表明2个皇后在同一斜线上。从而将隐约束转为了显约束。
说明:只需要两个函数即可完成n后问题,分别为place(int k)和queen(int t)。
其中place(int t)为判断函数,用于判断第k个皇后是否能放在某一位置;queen(int t)为求所有可行方案的函数,用于打印所有可行方案和可行方案总数。
代码如下:
// nQueen.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
int sum = 0;
//判断函数,判断第k个皇后是否可以放在某一位置(k,x[k])
bool place(int k,int *x)
{
for (int i = 1; i < k; i++)
{
if (x[i] == x[k] || abs(k - i) == abs(x[i] - x[k])) return false;
}
return true;
}
//求解可行解函数。
//输出:打印出n个皇后所在位置
void queen(int t,int n,int *x)
{
//n个皇后放置完毕
if (t > n&&n>0)
{
sum++;
for (int i=1;i<=n;i++)
{
cout << x[i];
}
cout << endl;
}
else
{
for (int j = 1; j <= n; j++) {
x[t] = j;
if (place(t, x)) {
queen(t + 1, n, x);
}
}
}
}
int main()
{
int n; //皇后个数
cout << "请输入皇后的个数:";
cin >> n;
int *x; //当前解
x = new int[n + 1];
for (int i=0;i<=n;i++)
{
x[i] = 0;
}
queen(1,n,x);
cout << sum << endl;
return 0;
}
执行结果: