数据结构编程回顾(三)八皇后问题(递归)

设计要求:八皇后问题是在8×8 的国际象棋棋盘上安放8
个皇后,要求没有一个皇后能够“吃掉”任何其他一个皇后,
即没有两个或多个皇后占据棋盘上的同一行、同一列或者同
一条对角线。
说明:在实际问题中,有相当一类问题需要找出它的解集合,
或者要找出某些约束条件下的最优解。求解时通常使用一种
称为回溯的方法来解决,所谓回溯就是走回头路,该方法是
在一定的约束条件下试探地搜索前进,若前进中受阻,则回
头另择通路继续搜索。

由于作者比较懒,当年就用了递归实现而已,没有用栈的非递归实现。

由定义可知,每行必定有且仅有一个皇后,使用一维数组存储即可,每个元素存储这一行元素的位置。

根据已知条件(同行、同列或同一一条线)不能放置两个皇后(后来知道皇后是可以横着走斜着走竖着走的,如果满足这些条件会被吃掉),判断第n行第i列是否能放置皇后:

int puts(int n,int i){
int j;

for(j=0;j<n-1;j++){
	if(queens[j]==i||((n-j)==(queens[n]-queens[j]))||((n-j)==(queens[j]-queens[n])))
	return 0;

}
return 1;}

递归体:

如果n==总行数,即0~n-1已经放置完成,则解法+1,并输出改解法。

否则,对这行的每个位置进行判断是否能放置,如果能,则进行下一行的放置,否则,退回上一层,继续测试上一层的下一个位置。

int queen(int n){
	if(n==num)
	{   c++;
		print();
		return 0;
	}
int i;
for(i=0;i<num;i++){
	queens[n]=i;
	if(puts(n,i)==1){
		queen(n+1);
	}

}
}

完整代码:

扫描二维码关注公众号,回复: 4723827 查看本文章
#include <iostream>
#include <string.h>

//八皇后问题
int queens[100];

int num;
int c;

using namespace std;
void print(){
	int i,j;
	cout<<endl<<"---------------"<<endl;
	cout<<"第"<<c<<"种解法"<<endl;
	for(i=0;i<num;i++){
		for(j=0;j<num;j++){

			if(queens[i]==j)
			cout<<'T';
			else
			cout<<'O';

			cout<<' ';
		}

		cout<<endl;
	}

}
int puts(int n,int i){
int j;

for(j=0;j<n-1;j++){
	if(queens[j]==i||((n-j)==(queens[n]-queens[j]))||((n-j)==(queens[j]-queens[n])))
	return 0;

}
return 1;}
int queen(int n){
	if(n==num)
	{   c++;
		print();
		return 0;
	}
int i;
for(i=0;i<num;i++){
	queens[n]=i;
	if(puts(n,i)==1){
		queen(n+1);
	}

}
}

int main()
{
	cout<<"N queens problem\n"<<"pls input n:";

	cin>>num;
    queen(0);

    cout<<"共有"<<c<<"种解法.";
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36614557/article/details/81517210