【问题描述】在n*n的方格棋盘放置n个皇后,要求每个皇后不同行,不同列、不同左右对角线。
【问题求解】采用整数数组q[N]存放n皇后问题的求解结果,因为每行只能放一个皇后,q[i](1<=I<=n)的值表示第i个皇后所在的列号,即该皇后放在(i,q[i])的位置上。(为了简便,不使用q[0]元素)。
对于(i,j)位置上的皇后,是否与已放好的皇后(k,q[k])(1<=k<=i-1)有冲突呢?显然它们不同列,若同列则有q[k]==j;对角线有两条,若它们在任一条对角线上,则构成一个等腰直角三角形,即|q[k]-j|==|i-k|。所以,只要满足以下条件则存在冲突,否则不冲突;
q[k]==j || abs(q[k]-j)==abs(i-k)
注意:abs()函数为求绝对值函数。
对应的输出n皇后问题所有解的完整程序如下:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define N 20 //最多皇后个数
using namespace std;
int q[N]; //存放各皇后所在的列号,即(i,q[i])为一个皇后位置
int num = 0; //累计解个数
void dispasolution(int n) {
cout << "第" <<++num << "个解:";
for (int i = 1; i <= n;i++) {
cout << "(" << i << ","<<q[i] << ")";
}
cout << endl;
}
bool place(int i,int j) { //测试(i,j)位置能否摆放皇后
if (i==1) { //第一个皇后总是可以放置
return true;
}
int k = 1;
while(k<i){
if ((q[k]==j)||(abs(q[k]-j)==abs(i-k))) {
return false;
}
k++;
}
return true;
}
void queen(int i,int n) { //放置1-i皇后
if (i>n) {
dispasolution(n); //所有皇后放置结束
}
else {
for (int j = 1; j <= n;j++) { //在第i行上试探每一个列j
if (place(i,j)) { //在第i行找到一个合适的位置(i,j)
q[i] = j;
queen(i+1,n); //继续放置下一个
}
}
}
}
int main() {
int n; //n为存放实际皇后个数
cout << "皇后问题(n<20)n=" << endl;
cin >> n;
if (n>20) {
cout << "n值太大,不能求解" << endl;
}
else {
cout << "皇后问题求解如下:" << endl;
queen(1, n); //放置1-n皇后
}
system("pause");
return 0;
}
输出为:
皇后问题(n<20)n=
6
皇后问题求解如下:
第1个解:(1,2)(2,4)(3,6)(4,1)(5,3)(6,5)
第2个解:(1,3)(2,6)(3,2)(4,5)(5,1)(6,4)
第3个解:(1,4)(2,1)(3,5)(4,2)(5,6)(6,3)
第4个解:(1,5)(2,3)(3,1)(4,6)(5,4)(6,2)
请按任意键继续. . .