用 stack 解决“八皇后问题”

题目:利用栈结构实现八皇后问题。
   八皇后问题19世纪著名的数学家高斯于1850年提出的。他的问题是:在8*8的棋盘上放置8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列、同一斜线上。请设计算法打印所有可能的摆放方法。
   提示:
   1、可以使用递归或非递归两种方法实现
   2、实现一个关键算法:判断任意两个皇后是否在同一行、同一列和同一斜线上


#include <iostream>
#include <stack>
using namespace std;
#define N 8  //8个格子
bool isocupy[N] = { 0 };//表示该行时候被占用了
struct queen{//记录每个皇后的坐标
	int x;
	int y;
};
stack <queen> s, temp;
char pic[N][N] = { '.' };//用来输出图像
int n = 0;//表示可能数目
bool judge(int x, int y);//判断是否处于同一行、同一列、同一斜线上
void sovled();
void print();//打印可能结果
int main(){
	memset(pic, '.', sizeof(pic));
	sovled();
}
void sovled(){
	if (s.empty()){	//如果栈空
		queen temp_q;
		temp_q.x = 0;
		for (temp_q.y = 0; temp_q.y < N; temp_q.y++){
			s.push(temp_q);
			isocupy[temp_q.y] = true;
			sovled();
			s.pop();
			isocupy[temp_q.y] = false;
		}
	}
	else{
		if (s.size() == N){//如果栈满
			temp = s;
			n++;
			print();
			return;
		}
		else{
			queen temp_q;
			temp_q.x = s.top().x + 1;
			for (temp_q.y = 0; temp_q.y < N; temp_q.y++){
				if (judge(temp_q.x, temp_q.y)){//如果符合条件
					s.push(temp_q);
					isocupy[temp_q.y] = true;
					sovled();
					s.pop();
					isocupy[temp_q.y] = false;
				}
			}
		}
	}
}
bool judge(int x, int y){
	stack <queen> temp_ = s;
	while (!temp_.empty()){
		queen temp_q = temp_.top();
		if (isocupy[y] || (abs(temp_q.x - x) == abs(temp_q.y - y)))
			return false;
		temp_.pop();
	}
	return true;
}
void print(){
	for (int i = 0; i < N; i++){
		pic[temp.top().x][temp.top().y] = 'X';
		temp.pop();
	}
	for (int i = 0; i < N; i++){
		cout << endl;
		for (int j = 0; j < N; j++)
			cout << pic[i][j] << " ";
	}
	cout << endl << "----------------" << endl;
	memset(pic, '.', sizeof(pic));
	cout << "n= " << n << endl;
}


摘要: 八皇后问题要求在一个8*8的棋盘上放上8个皇后,使得每一个皇后既攻击不到另外七个皇后,也不被另外七个皇后所攻击.按照国际象棋的规则,一个皇后可以攻击与之处在同一行或同一列或同一斜线上的其他任何棋子.因此,八皇后问题等于要求八个皇后中的任意两个不能被放在同一行或同一列或同一斜线上。 而本课程设计本人的目的也是通过用c++语言平台将一个8*8的棋盘上放上8个皇后,使得每一个皇后既攻击不到另外七个皇后,也不被另外七个皇后所攻击的92种结构予以实现. 使用递归方法最终将其问题变得一目了然,更加易懂。 关键词: 八皇后 ; c++ ; 递归法 目 录 1. 课题综述 1 1. 1课题的来源及意义 1 1. 2 面对的问题 1 2. 需求分析 1 2. 1 涉及到的知识 1 2. 2 软硬件的需求 1 2. 3 功能需求 2 3. 概要设计 2 4. 详细设计和实现 2 4. 1 算法描述及详细流程图 2 4.1.1 算法描述 3 4.1.2 算法流程图 3 5. 代码编写及详细注释 4 6. 程序调试 7 6. 1调试过程、步骤及遇到的问题 7 7. 运行与测试 7 7.1运行演示 7 总 结 9 致 谢 10 参考文献 11 . 1. 课题综述 1. 1课题的来源及意义 八皇后问题是一个古老而著名的问题,该问题是十九世纪著名的数学家高斯1850年提出的。 在国际象棋中,皇后是最有权利的一个棋子;只要别的棋子在它的同一行或同一列或同一斜线(正斜线或反斜线)上时,它就能把对方棋子吃掉。所以高斯提出了一个问题:在8*8的格的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后都不能处于同一列、同一行、或同一条斜线上面,问共有多少种解法。 到了现代,随着计算机技术的飞速发展,这一古老而有趣的数学游戏问题也自然而然的被搬到了计算机上。运用所学计算机知识来试着解决这个问题是个锻炼和提高我自己编程能力和独立解决问题能力的好机会,可以使我增强信心,为我以后的编程开个好头,故我选择了这个有趣的课题。 1. 2 面对的问题 1) 解决冲突问题: 这个问题包括了行,列,两条对角线; 列:规定每一列放一个皇后,不会造成列上的冲突; 行:当第I行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以I为下标的标记置为被占领状态; 2) 使用数据结构的知识,用递归法解决问题。 2. 需求分析 2. 1 涉及到的知识 本次课程设计中,用到的主要知识有:递归法的运用,for语句的灵活运用,数据结构中树知识的灵活运用、及数组的掌握。 2. 2 软硬件的需求 1)系统要求:win98以上操作系统; 2) 语言平台:tc++或vc++6.0; 2. 3 功能需求 当运行程序时,在屏幕上显示每一种方法八个皇后的相对位置,要用比较直观 的界面显示。 3. 概要设计 本课件学生是用循环递归循环来实现的,分别一一测试了每一种摆法,并把它拥有的92种变化表现出来。在这个程序中,我的主要思路以及思想是这样的: 1)解决冲突问题: 这个问题包括了行,列,两条对角线; 列:规定每一列放一个皇后,不会造成列上的冲突; 行:当第I行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以I为下标的标记置为被占领状态; 对角线:对角线有两个方向。在这我把这两条对角线称为:主对角线和从对角线。在同一对角线上的所有点(设下标为(i,j)),要么(i+j)是常数,要么(i-j)是常数。因此,当第I个皇后占领了第J列后,要同时把以(i+j)、(i-j)为下标的标记置为被占领状态。 2)数据结构的实现 而对于数据结构的实现,学生则是着重于: 数组a[I]:a [I]表示第I个皇后放置的列;I的范围:1..8; 对角线数组:b[j](主对角线),c[j](从对角线),根据程序的运行,去决定主从对角线是否放入皇后; 4. 详细设计和实现 4. 1 算法描述及详细流程图 4.1.1 算法描述 A、 数据初始化。 B、 从n列开始摆放第n个皇后(因为这样便可以符合每一竖列一个皇后的要求),先测试当前位置(n,m)是否等于0(未被占领)。如果是,摆放第n个皇后,并宣布占领(记得姚横列竖列斜列一起设置),接着进行递归;如果不是,测试下一个位置(n,m+1),但是如果当n<=8,m=8时,发现此时已无法摆放时,便要进行回溯。从问题的某一种可能出发,搜索从这种情况能出发,继续搜索,这种不断“回溯”的寻找解的方法,称为“回溯法”。 C、使用数组实现回溯法的思想。 D、当n>8时,便打印出结果。 E、输出函数我使用printf输出,运行形式为:第m种方法为:* * * * * * * *
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值