马的遍历问题求解.doc
《马的遍历问题求解.doc》由会员分享,可在线阅读,更多相关《马的遍历问题求解.doc(23页珍藏版)》请在沃文网上搜索。
1、 摘要马步遍历问题与骑士巡游(knights tour)问题是指在有88方格的国际象棋棋盘上进行奇异的骑士L型(L-shaped)移动的问题。而骑士巡游问题实际是带有约束条件的马步遍历问题,因此在用程序求解的时候可以一并求解。中国象棋中马采用“日”字走法,对棋盘上马所在的结点,一步内到达的结点最 多有八个,即假设马所在点的坐标为(i,j),那么其它八个结点的坐标为(i+1,j+2),(i+2,j+1),(i+2,j-1),(i+1,j-2),(i-1,j-2),(i-2,j-1),(i-2,j+1),(i-1,j+2)把这些点看作马所在点的邻接点,所以可以采用类似图的深度优先遍历,以马所在点为
2、初始点对整个棋盘进行遍历。然后按遍历的顺序输出结点。 关键词:象棋,遍历,数组I攀枝花学院本科课程设计报告(论文) 目 录摘 要1 概述1 1.1 前言1 1.1.1问题描述1 1.1.2课程设计的目的12 流程图23 设计思路34 数据结构设计45 功能函数算法分析5 5.1 计算一个点周围有几个点5 5.2 寻找下一个方向函数5 5.3 栈的相关函数6 5.4 马的遍历函数7 5.5 主函数9 5.6棋盘初始化函数10 5.7 标记初始化函数10结论11参考文献12附录A:程序代码13I 1 概述1.1前言1.1.1问题描述根据中国象棋棋盘,对任一位置上放置的一个马,均能选择一个合适的路线
3、,使得该棋子能按象棋的规则不重复地走过棋盘上的每一位置。 要求: (1)依次输出所走过的各位置的坐标。 (2)最好能画出棋盘的图形形式,并在其上动态地标注行走过程。 (3)程序能方便地地移植到其它规格的棋盘上。1.1.2课程设计的目的 使学生进一步理解和掌握课堂上所学各种基本抽象数据类型的逻辑结构、存储结构和操作实现算法,以及它们在程序中的使用方法。1) 使学生进一步理解和掌握课堂上所学各种基本抽象数据类型的逻辑结构、存储结构和操作实现算法,以及它们在程序中的使用方法。2) 使学生掌握软件设计的基本内容和设计方法,并培养学生进行规范化软件设计的能力。3) 使学生掌握使用各种计算机资料和有关参考
4、资料,提高学生进行程序设计的基本能力。- 2 -I攀枝花学院本科课程设计报告(论文) 开始输入入口点横坐标横坐标在110之间输入入口点纵坐标纵坐标在19之间显示马遍历路径结束 2 流程图 假 真 假 攀枝花学院本科课程设计报告(论文) 3 设计思路首先,中国象棋是10*9的棋盘,马的走法是“马走日”,忽略“蹩脚马”的情况。其次,这个题目采用的是算法当中的深度优先算法和回溯法:在“走到”一个位置后要寻找下一个位置,如果发生“阻塞”的情况,就是后面走不通的情况,则向后回溯,重新寻找。在寻找下一步的时候,对周围的这几个点进行比较,从而分出优劣程度,即看它们周围可以走的点谁最少,然后就走那条可走路线最
5、少的那条。经过这样的筛选后,就会为后面的路径寻找提供方便,从而减少回溯次数。最后,本程序的棋盘和数组类似,因而采用数组进行存储,同时因为有回溯,所以采用栈的方法,并且为了最后打印方便,采用的是顺序栈的方法。同时还有八个方向的数组,和为栈设计的每个点周围的八个方向那些可以走的数组。 3I攀枝花学院本科课程设计报告(论文) 4 数据结构设计同上面述,棋盘采用数组形式,并且这里的数组比棋盘的数组规模稍大,因为为了判断的方便,这里在棋盘周围各加了两层“墙”。具体数据结构定义如下:int chessboard1413; /采用最大的中国象棋10*9制的int CanPass14138; /每个棋子的八个
6、方向哪些可以走typedef struct /棋盘的八个方向 int x,y;direction;direction dir8=2,1,1,2,-1,2,-2,1,-2,-1,-1,-2,1,-2,2,-1; /八个方向typedef struct /栈的节点结构 int x,y; /走过位置 int di; /走向下一个方向pathnode;typedef structpathnode pa90; /栈的容量最大为90int top; /栈顶path; /顺序栈 5 功能函数算法分析5.1 计算一个点周围有几个点函数int Count(int x,int y) 该函数实现的功能是在遍历的过程
7、当中计算一个点周围有几个方向可以走,从而为后面的筛选提供依据。int Count(int x,int y) /计算每个节点周围有几个方向可以走int count=0,i=0;for(i=0;i8;i+)if(chessx+1+diri.xy+1+diri.y=0)count+;return count;5.2寻找下一个方向函数int Find_Direction(int x,int y)该函数的功能是在走过一个点之后,寻找下一个适合的点,如果找到返回正常的方向值,否则返回-1。int Find_Direction(int x,int y) /寻找下一个方向int dire,min=9,coun
8、t,d=9;for(dire=0;direcount) min=count; d=dire; if(dtop=-1;int Push_Path(path *p,pathnode t) /压节点及其向下一位移动的方向入栈if(p-top=89)return -1;elsep-top+;p-pap-top.x=t.x;p-pap-top.y=t.y;p-pap-top.di=t.di;return 1;int Empty(path p) /判断栈是否为空if(p.topx=p-pap-top.x;t-y=p-pap-top.y;t-di=p-pap-top-.di;return 1;5.4马的遍历
9、函数:void Horse(int x,int y)这是该算法的精华部分,x,y表示入口地点,v表示棋盘类型即中国象棋,这个函数主体是一个循环,循环里面始终是在找下一个点,如果找到就将该点进栈,找不到则退栈。直到发生栈为空时退栈或循环结束,前一种情况时会提示找不到路径(虽然不会发生,但是为逻辑严密性依然要如此),后一种情况则打印出走过的正确路径和走过之后的数组。void Horse(int x,int y) /x,y表示出发位置 /马遍历函数int num=1,t,i;path p;pathnode f;Init_Path(&p);for(num=1;num=90;num+)t=Find_Di
10、rection(x,y);if(t!=-1) /正常找到下一个方向的情况下chessboardx+1y+1=num;f.x=x;f.y=y;f.di=t;Push_Path(&p,f);x=x+dirt.x;y=y+dirt.y;else if(num=64+26*v&chessboardx+1y+1=0) /最后一次时t肯定是-1chessboardx+1y+1=num;f.x=x;f.y=y;f.di=t;Push_Path(&p,f,v);elseif(Pop_Path(&p,&f)=-1) /出栈且栈为空的情况printf(无法为您找到一条适合的路径!n);exit(0);num-=2
11、; /返回前一个点x=f.x;y=f.y;CanPathx+1y+1f.di=1; /遍历不成功,即这个方向不通 /根据栈中信息打印马的行走路径printf(马的遍历路径如下:n );for(i=0;i,p.pai.x,p.pai.y);if(i+1)%(8)=0)printf(bb n-);5.5主函数:int main()提示输入起点位置,这里的起点位置就是日常生活观念中的顺序,开始点是(1,1),而不是数组中的初始位置(0,0),输入错误则提示重新输入,时间复杂度为。int main() /主函数int x,y; char ch=y; while(ch=y)printf( 中国象棋马的遍
- 1.请仔细阅读文档,确保文档完整性,对于不预览、不比对内容而直接下载带来的问题本站不予受理。
- 2.下载的文档,不会出现我们的网址水印。
- 3、该文档所得收入(下载+内容+预览)归上传者、原创作者;如果您是本文档原作者,请点此认领!既往收益都归您。
下载文档到电脑,查找使用更方便
10 积分
下载 | 加入VIP,下载更划算! |
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 遍历 问题 求解