八皇后问题递归C语言

合集下载

八皇后问题

八皇后问题

八皇后问题八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。

该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

高斯认为有76种方案。

1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。

对于八皇后问题的实现,如果结合动态的图形演示,则可以使算法的描述更形象、更生动,使教学能产生良好的效果。

下面是用Turbo C实现的八皇后问题的图形程序,能够演示全部的92组解。

八皇后问题动态图形的实现,主要应解决以下两个问题。

(1)回溯算法的实现(a)为解决这个问题,我们把棋盘的横坐标定为i,纵坐标定为j,i和j的取值范围是从1到8。

当某个皇后占了位置(i,j)时,在这个位置的垂直方向、水平方向和斜线方向都不能再放其它皇后了。

用语句实现,可定义如下三个整型数组:a[8],b[15],c[24]。

其中:a[j-1]=1 第j列上无皇后a[j-1]=0 第j列上有皇后b[i+j-2]=1 (i,j)的对角线(左上至右下)无皇后b[i+j-2]=0 (i,j)的对角线(左上至右下)有皇后c[i-j+7]=1 (i,j)的对角线(右上至左下)无皇后c[i-j+7]=0 (i,j)的对角线(右上至左下)有皇后(b)为第i个皇后选择位置的算法如下:for(j=1;j<=8;j++) /*第i个皇后在第j行*/if ((i,j)位置为空))/*即相应的三个数组的对应元素值为1*/{占用位置(i,j)/*置相应的三个数组对应的元素值为0*/if i<8为i+1个皇后选择合适的位置;else 输出一个解}(2)图形存取在Turbo C语言中,图形的存取可用如下标准函数实现:size=imagesize(x1,y1,x2,y2) ;返回存储区域所需字节数。

八皇后问题MIPS实现方案

八皇后问题MIPS实现方案
八皇后问题 2010012107 季涛 使用工具:MARS 1.计算的规则和任务 国际象棋中的皇后可以吃掉与它在同一行、同一列、同一对角线上的棋子。 八皇后问题,即在 8×8 的国际象棋棋盘上放置 8 个皇后,要求任意两个皇后不能 在同一行、同一列或同一条对角线上。求出如此放置方法的种数。 一种解决问题的思路是一行放置皇后,如果当前放置的皇后与前面的皇后不 存在冲突时,则继续摆下一个皇后,否则跳到上一个皇后,重新摆置。 2.函数的 C 语言形式描述 #include <stdio.h > #include <math.h > int Site[8]; int Queen(int n, int QUEENS, int); int Valid(int n); void main() { int m; int iCount = 0; int n ; printf("Eight Queen problems!Please enter the number of queens:") ; scanf("%d" , &n) ; m=Queen(0,n , iCount); printf("%d\n",m); return ; } /*-----------------Queen:递归放置第 n 个皇后---------------*/ int Queen(int n, int QUEENS, int iCount) { int i; if(n == QUEENS) { iCount=iCount+1; return iCount; }
实验结果截图:
#store the result in $s0
#print and exit li $v0,1 move $a0,$s0 syscall li $v0,10 syscall #Function Queen Queen: addi $sp,$sp,-24 sw $ra,20($sp) sw $v0,16($sp) sw $a1,12($sp) sw $a2,8($sp) sw $s3,4($sp) addi $s7,$0,1 #initial $s7 which is i sw $s7,0($sp) #refresh and save i bne $a0,$a1,qLoop #n==QUEENS addi $a2,$a2,1#iCount=iCount+1 sw $a2,8($sp) #refresh and save iCount j qExit qLoop: lw $a1,12($sp) #load n to $a1 sll $t0,$a1,2 #$t0=4*n add $s3,$t0,$gp #$s3 is the address of site[n] sw $s7,0($s3) #site[n]=i #let Valid to judge jal Valid beqz $v1,else #Valid==1 addi $a1,$a1,1#n=n+1 jal Queen move $a2,$v0 #put the result into $a2 sw $a2,8($sp) #refresh and save $a2 #Valid==0 else: lw $s7,0($sp) #load the previous i ##### addi $s7,$s7,1 #i=i+1 sw $s7,0($sp) #refresh and save i

八皇后源代码及流程图

八皇后源代码及流程图

目录一需求分析 (1)1.1程序的功能: (1)1.2程序的输入输出要求: (1)二概要设计 (3)2.1程序的主要模块: (3)2.2程序涉及: (3)三详细设计 (3)3.1相关代码及算法 (4)3.1.1 定义相关的数据类型如下:....................... 错误!未定义书签。

3.1.2 主模块类C码算法: (4)3.1.3 画棋盘模块类C码算法 (5)3.1.4 画皇后模块类C码算法: (5)3.1.5 八皇后摆法模块(递归法): (6)3.1.6 初始化模块 (7)3.1.7 输出摆放好的八皇后图形(动态演示): (7)3.2相关流程图 (9)四调试分析 (12)五设计体会 (13)六附录 (13)七参考文献 (17)一需求分析1.1 程序功能:八皇后问题是一个古老而著名的问题。

该问题是十九世纪著名的数学家高斯1850年提出的。

八皇后问题要求在一个8*8的棋盘上放上8个皇后,使得每一个皇后既攻击不到另外七个皇后,也不被另外七个皇后所攻击.按照国际象棋的规则,一个皇后可以攻击与之处在同一行或同一列或同一斜线上的其他任何棋子,问有多少种不同的摆法?并找出所有的摆法。

因此,八皇后问题等于要求八个皇后中的任意两个不能被放在同一行或同一列或同一斜线上。

本程序通过对子函数void qu(int i)的调用,将八皇后的问题关键通过数据结构的思想予以了实现。

虽然题目以及演算看起来都比较复杂,繁琐,但在实际中,只要当一只皇后放入棋盘后,在横与列、斜线上没有另外一只皇后与其冲突,再对皇后的定位进行相关的判断。

即可完成。

如果在这个程序中,我们运用的是非递归的思想,那么将大量使用if等语句,并通过不断的判断,去推出答案,而且这种非递归的思想,大大的增加了程序的时间复杂度。

如果我们使用了数据结构中的算法后,那么程序的时间复杂度,以及相关的代码简化都能取得不错的改进。

这个程序,我运用到了数据结构中的栈、数组,以及树和回溯的方法。

八皇后问题代码实现

八皇后问题代码实现

八皇后问题代码实现/*代码解析*//* Code by Slyar */ #include &lt;stdio.h&gt;#include&lt;stdlib.h&gt; #define max 8 int queen[max], sum=0; /* max为棋盘最大坐标*/ void show() /* 输出所有皇后的坐标*/{ int i; for(i = 0; i &lt; max; i++){ printf("(%d,%d) ", i, queen[i]); }printf("\n"); sum++;} int check(int n) /* 检查当前列能否放置皇后*/{ int i; for(i = 0; i &lt; n; i++) /* 检查横排和对角线上是否可以放置皇后*/ { /* ///题目的要求是所有皇后不在同一横排、竖排、对角线上。

1、queen[n]值为竖排号,可看为Y轴上值。

n值为横排号,可看为X轴上值。

2、(1)先从横坐标第n点排开始放皇后,再放第n+1,所有不会同一横坐标点即同一竖排。

(2)queen[i] == queen[n]时即y坐标相等,即在同一横排,此时判断不合规则点。

(3)abs(queen[i] - queen[n]) == (n - i),可变形为(queen[n] - queen[i]) /(n - i)==tan45°或tan135° 由公式可得出,点(n,queen[n])与点(i,quuen[i])在同一条左斜线135°或右斜45°,即国际象棋上的每个格子的两条斜角线。

3、由2即可得出当前格式是否能放置一个皇后。

*/ if(queen[i] == queen[n] || abs(queen[i] - queen[n]) == (n - i)) { return1; } } return 0;} void put(int n) /* 回溯尝试皇后位置,n为横坐标*/{ int i; for(i = 0; i &lt; max;i++) { queen[n] = i; /* 将皇后摆到当前循环到的位置*/ if(!check(n)){ if(n == max - 1){ show(); /* 如果全部摆好,则输出所有皇后的坐标*/ } else { put(n + 1); /* 否则继续摆放下一个皇后*/ } } }} int main(){ put(0); /*从横坐标为0开始依次尝试*/ printf("TTTTTT----%d\n", sum); //system("pause"); //while(1); return 0;}/*算法系列---回溯算法引言寻找问题的解的一种可靠的方法是首先列出所有候选解,然后依次检查每一个,在检查完所有或部分候选解后,即可找到所需要的解。

C++课程设计八皇后问题

C++课程设计八皇后问题

安徽建筑工业学院数据结构设计报告书院系数理系专业信息与计算科学班级11信息专升本学号11207210138姓名李晓光题目八皇后指导教师王鑫1.程序功能介绍答:这个程序是用于解决八皇后问题的。

八皇后问题等于要求八个皇后中的任意两个不能被放在同一行或同一列或同一斜线上。

做这个课题,重要的就是先搞清楚哪个位置是合法的放皇后的位置,哪个不能,要先判断,后放置。

我的程序进入时会让使用者选择程序的功能,选【1】将会通过使用者自己手动输入第一个皇后的坐标后获得答案;选【2】将会让程序自动运算出固定每一个皇后后所有的排列结果。

2.课程设计要求答:(1)增加函数,完成每输入一组解,暂停屏幕,显示“按任意键继续!”。

(2)完善程序,编程计算八皇后问题共有集中排列方案。

(3)增加输入,显示在第一个皇后确定后,共有几组排列。

(4)将每组解的期盼横向排列输出在屏幕上,将五个棋盘并排排列,即一次8行同时输出5个棋盘,同样完成一组解后屏幕暂停,按任意键继续。

(5)求出在什么位置固定一个皇后后,解的数量最多,在什么位置固定皇后后,解的数量最少,最多的解是多少,最少的解是多少,并将最多,最少解的皇后位置及所有的解求出,同样5个一组显示。

3.对课程题目的分析与注释答:众所周知的八皇后问题是一个非常古老的问题,问题要求在一个8*8的棋盘上放上8个皇后,使得每一个皇后既攻击不到另外七个皇后,也不被另外七个皇后所攻击。

按照国际象棋的规则,一个皇后可以攻击与之处在同一行或同一列或同一斜线上的其他任何棋子。

因此,本课程设计的目的也是通过用C++语言平台在一个8*8的棋盘上放上8个皇后,使得每一个皇后既攻击不到另外七个皇后,也不被另外七个皇后所攻击的92种结构予以实现。

使用递归方法最终将其问题变得一目了然,更加易懂。

首先要用到类,将程序合理化:我编辑了一个盘棋8*8的类:class Board,还有个回溯法的类:class Stack,关键的类好了,然后编辑好类的成员,然后编辑主函数利用好这些类的成员,让其运算出结果。

八皇后以及N皇后问题分析

八皇后以及N皇后问题分析

⼋皇后以及N皇后问题分析⼋皇后是⼀个经典问题,在8*8的棋盘上放置8个皇后,每⼀⾏不能互相攻击。

因此拓展出 N皇后问题。

下⾯慢慢了解解决这些问题的⽅法:回溯法:回溯算法也叫试探法,它是⼀种系统地搜索问题的解的⽅法。

回溯算法的基本思想是:从⼀条路往前⾛,能进则进,不能进则退回来,换⼀条路再试。

在现实中,有很多问题往往需要我们把其所有可能穷举出来,然后从中找出满⾜某种要求的可能或最优的情况,从⽽得到整个问题的解。

回溯算法就是解决这种问题的“通⽤算法”,有“万能算法”之称。

N皇后问题在N增⼤时就是这样⼀个解空间很⼤的问题,所以⽐较适合⽤这种⽅法求解。

这也是N皇后问题的传统解法,很经典。

算法描述:1. 算法开始,清空棋盘。

当前⾏设为第⼀⾏,当前列设为第⼀列。

2. 在当前⾏,当前列的判断放置皇后是否安全,若不安全,则跳到第四步。

3. 在当前位置上满⾜条件的情况: 在当前位置放⼀个皇后,若当前⾏是最后⼀⾏,记录⼀个解; 若当前⾏不是最后⼀⾏,当前⾏设为下⼀⾏,当前列设为当前⾏的第⼀个待测位置; 若当前⾏是最后⼀⾏,当前列不是最后⼀列,当前列设为下⼀列; 若当前⾏是最后⼀⾏,当前列是最后⼀列,回溯,即清空当前⾏以及以下各⾏的棋盘,然后当前⾏设为上⼀⾏,当前列设为当前⾏的下⼀个待测位置; 以上返回第⼆步。

4.在当前位置上不满⾜条件: 若当前列不是最后⼀列,当前列设为下⼀列,返回到第⼆步; 若当前列是最后⼀列,回溯,即,若当前⾏已经是第⼀⾏了,算法退出,否则,清空当前⾏以及以下各⾏的棋盘,然后,当前⾏设为上⼀⾏,当前列设为当前⾏的下⼀个待测位置,返回第⼆步。

如何判断是否安全:把棋盘存储为⼀个N维数组a[N],数组中第i个元素的值代表第i⾏的皇后位置,这样便可以把问题的空间规模压缩为⼀维O(N),在判断是否冲突时也很简单, ⾸先每⾏只有⼀个皇后,且在数组中只占据⼀个元素的位置,⾏冲突就不存在了, 其次是列冲突,判断⼀下是否有a[i]与当前要放置皇后的列j相等即可。

八皇后问题的解决完整

八皇后问题的解决完整

八皇后问题的解决完整 Standardization of sany group #QS8QHH-HHGX8Q8-GNHHJ8-HHMHGN#淮阴工学院数据结构课程设计报告设计题目:八皇后2008 年 6 月 25 日设计任务书摘要:八皇后问题要求在一个8*8的棋盘上放上8个皇后,使得每一个皇后既攻击不到另外七个皇后,也不被另外七个皇后所攻击.按照国际象棋的规则,一个皇后可以攻击与之处在同一行或同一列或同一斜线上的其他任何棋子.因此,八皇后问题等于要求八个皇后中的任意两个不能被放在同一行或同一列或同一斜线上。

而本课程设计本人的目的也是通过用c++语言平台将一个8*8的棋盘上放上8个皇后,使得每一个皇后既攻击不到另外七个皇后,也不被另外七个皇后所攻击的92种结构予以实现.使用递归方法最终将其问题变得一目了然,更加易懂。

关键词:八皇后 ; c++ ; 递归法目录.1. 课题综述1. 1课题的来源及意义八皇后问题是一个古老而着名的问题,该问题是十九世纪着名的数学家高斯1850年提出的。

在国际象棋中,皇后是最有权利的一个棋子;只要别的棋子在它的同一行或同一列或同一斜线(正斜线或反斜线)上时,它就能把对方棋子吃掉。

所以高斯提出了一个问题:在8*8的格的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后都不能处于同一列、同一行、或同一条斜线上面,问共有多少种解法。

到了现代,随着计算机技术的飞速发展,这一古老而有趣的数学游戏问题也自然而然的被搬到了计算机上。

运用所学计算机知识来试着解决这个问题是个锻炼和提高我自己编程能力和独立解决问题能力的好机会,可以使我增强信心,为我以后的编程开个好头,故我选择了这个有趣的课题。

1. 2 面对的问题1)解决冲突问题:这个问题包括了行,列,两条对角线;列:规定每一列放一个皇后,不会造成列上的冲突;行:当第I行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以I为下标的标记置为被占领状态;2)使用数据结构的知识,用递归法解决问题。

八皇后问题的动态求解

八皇后问题的动态求解
要方法 。 在 N后 问 题 中 .由 于 皇 后 的摆 放 位 置 不 能通 过 某 种 公 式 或
3 动 态 求解 8皇 后 问 题
通 常 编程 求 解 N后 问题 ,只 能看 到求 解 的 结 果 ,观 察 不 到 求 解 过 程 中 的 试 探 和 回溯 的 过 程 。 以 8皇 后 问 题 为 例 ,用 C #
中 ,按 照深 度 优 先 的 策 略 ,从 根 结 点 出 发搜 索 解 空 间树 。算 法 搜 索 到解 空 间树 的任 一 结 点 时 ,总 是先 判 断该 结 点是 否肯 定 不 包 含 问题 的解 。如 果 肯 定 不 包 含 ,则跳 过对 以该 结 点 为根 的子 树 的系 统 搜 索 ,逐 层 向 其 祖 先 结 点 回溯 。 否 则 ,进 入 该 子 树 , 继 续 按 深 度 优先 的策 略 进 行 搜 索 。用 该 方 法 可 以 系 统 地搜 索 一 个 问 题 的所 有解 或任 一 解 , “ 回溯 法 ” 也 是 递 归 过 程 的 一 种 重


i(u g () / 口 第 n个 皇 后位 置 合 法 , 归 放 置 fJ d en) / 果 女 递 } n 1 皇 后 涕 + 个
{ L y e n n 4 1: aLeabharlann Qu e ( ) - )

开始 求 解 ” 钮 的单 击 事 件 按
p ia e v i t L y r t od b n a v

, 入 本 函 数 前 , N× 格 棋盘 的 前 1 已 经 放 置 了 i / 进 在 N 一 列 —
叭 个皇后o
iiN 则输 出 得 到 的 一个 解 决 方 案 ; f> ) (
es le
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include<stdio.h>
#include<math.h>
const int NUM=8;//八皇后问题(NUM=8)
static int count=0;
void output(int array[][NUM]);//八皇后分布输出
int judge(int array[][NUM],int row,int column);//判定函数void search(int array[][NUM],int row);//搜索函数
int main()
{
int i,j;
int box[NUM][NUM];
for(i=0;i<NUM;i++)
{
for(j=0;j<NUM;j++)
box[i][j]=0;
}
//output(box);
search(box,0);
printf("八皇后分布共有%d 种。

\n",count);
return 0;
}
void output(int array[][NUM])
{
int i,j;
for(i=0;i<NUM;i++)
{
for(j=0;j<NUM;j++)
{
printf("%d ",*(*(array+i)+j));
}
printf("\n");
}
}
int judge(int array[][NUM],int row,int column)
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<NUM;j++)
{
if(array[i][j]==1)
{
if(j==column) return 0;//判断是否在同一列
if(abs(row-i)==abs(column-j)) return 0;//判断是否在同一斜线上}
}
}
return 1;
}
void search(int array[][NUM],int row)
{
int j;
//for(i=0;i<NUM;j++)
//{
for(j=0;j<NUM;j++)
{
if(!judge(array,row,j))
{
//printf("%d ",judge(array,row,j));
continue;
}
array[row][j]=1;
if(row==NUM-1)
{
//array[row][j]=1;
count++;
printf("八皇后分布图:%d\n",count);
output(array);
array[row][j]=0;
continue;
}
else
search(array,row+1);
array[row][j]=0;
}
//}
return;
}。

相关文档
最新文档