n皇后的递归算法

【问题描述】在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)
请按任意键继续. . .

猜你喜欢

转载自blog.csdn.net/liu_hong_yan/article/details/109247518