- 1、本文档共5页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
实验十n皇后问题
算法设计与分析实验报告
姓名:杨勇涛
班级:计科102
一、实验名称:n皇后问题
时间:2012年4月25日,星期三,第四节
地点:12#311
二、实验目的及要求
在n*n格的棋盘上放置彼此不受攻击的n皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列后统一斜线上的棋子。N皇后问题等价于在n*n格的棋盘上放置n个皇后,任何2个皇后不放在同一行同一列或同一列统统一些线上。
三、实验环境
VC++
四、实验内容
从键盘上输入n皇后的数目,输出所有的结果
五、算法描述及实验步骤
N×N皇后问题的求解过程就是一个试探回逆的过程。如图-1
(图1-1)
1、首先查找第一行的可放位置,第一行全部可以放,那么我们就先将第一个皇后放在(0,0)点。
(图1-2)
2、再查找第二行,由于第一行的(0,0)已经放了皇后,故第二行的(1,0)和(1,1)都能放皇后了,可放的就是(1,2)和(1,3)点,在(1,2)放上皇后。
(图1-3)
3、再查找第三行,查找所以发现第三行没有可放的位置了,回逆到第二行讲皇后放到(1,3)再查找第3行。如果还不行,就回到第一行将第一行的皇后放人下一个可放的点,依次类推,查找N×N上的所以可放的位置,直到第一行所以位置被放完,输出结果。
4、根据上面的规律可以发现,对于一个皇后放在坐标(x,y),它的下一行位置为(x-1,y)(x,y)(x+1,y)的坐标都不能再放皇后。我们用一个数组来存放本行能放皇后的点。用循环来查找上面行对本行的影响
#include math.h
#include iostream
using namespace std;
bool valid(int i,int j);//判断安置元素的合法性
void trial(int i); //递归安置元素
void print(); //显示布局
int q; //皇后数
int *a; //存储布局元素
int count = 0; //合法布局的序号
int main(int argc, char* argv[])
{
cout请输入皇后数:endl;
cinq;
a = new int[q*q];
for(int j=0;jq*q;j++)
a[j] = 0;
trial(0);
cout布局完毕endl;
return 0;
}
void trial(int i) //递归安置元素
{
if(i=q)
print();
else
for(int j=0;jq;j++)
{
a[i*q+j] = 1;
if(valid(i,j))
trial(i+1);
a[i*q+j] = 0;
}
}
bool valid(int i,int j) //判断安置元素的合法性
{
bool b=true;
for(int i1=0;i1i;i1++)
for(int j1=0;j1q;j1++)
if(a[i1*q+j1]==1)
{
if(j1==j)//判断是否在同一列
b = false;
else if(abs(i-i1)==abs(j-j1))//判断是否在对角线
b = false;
}
return b;
}
void print() //显示布局
{
count++;
cout第 count 种布局:endl;
for(int m=0;mq;m++)
{
for(int n=0;nq;n++)
{
couta[m*q+n] ;
}
coutendl;
}
cout----------------------------------------endl;
}
文档评论(0)