马踏棋盘分析文档

合集下载

第七次实验 马踏棋盘问题

第七次实验  马踏棋盘问题
桂林电子科技大学
数学与计算科学学院综合性、设计性实验报告
实验室:06406实验日期:2015年05月29日
院(系)
信息与计算科学系
年级、专业、班
1300710226
姓名
庞文正
成绩
课程
名称
数据结构实验
实验项目
名 称
马踏棋盘问题
指导
教师
教师
评语
教师签名:
年 月 日
一 ,实验目的
加深对图的理解,培养解决实际问题的编程能力。根据数据对象的特性,学会数据组织的方
start.y--;
curstep=1; //第一步
Move(start); //求解
}
五,实验结果分析或总结
运行半天不出来,比如输入 2 2还以为算法有误,后来想通了,真开心!
{n");
scanf("%d%d",&start.x,&start.y);
}
else
{
break;
}
}
for(i=0;i<8;i++) //初始化棋盘个单元位置
{
for(j=0;j<8;j++)
{
chessboard[i][j]=0;
}
}
start.x--;
格子具有集合性,故考虑使用无向图来表示格子及其间关系;以邻接表作为该无向图中结点与相邻8个结点(4黑4白)的存储结构;以顶点表存储格子,每格为顶点表中一结点,其指针域指向该顶点所能到达的第一个结点。
表头结点:
Vex
x
y
link
Vex:头结点所在的序号
x:头结点所在的横坐标;

马踏棋盘

马踏棋盘

马踏棋盘学院专业学号学生姓名指导教师年月日摘要:国际象棋想必大家都玩过,但你有没有想过,让一个“马”遍历国际象棋8*8的棋盘,有没有可能?如果有可能,在给定起点的情况下,有多少种可能?下面,我们将用计算机来模拟“马”对棋盘的遍历.关键字:回溯算法贪心算法遍历正文:已知国际象棋为8×8棋盘,共64个格,规则中,马按照如图所示规则移动。

将马放在任意方格中,令马遍历每个方格一次且仅一次,编制非递归程序,将数字1,2, (64)照马的行走路线依次填入一个8×8的方阵,并输出结果。

通过结合图示,我们不难发现,当马的起始位置(i,j)确定的时候,可以走到下列8个位置之一:(i-2,j+1)、(i-1,j+2)、(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,j)靠近棋盘的边缘,上述有些位置可能超出棋盘范围,成为不可达的位置。

8个可能位置可以用一维数组Htry1[0…7]和HTry2[0..7]来表示:Htry1:0 1 2 3 4 5 6 7-2 -1 1 2 2 1 -1 -2 Htry2:0 1 2 3 4 5 6 71 2 2 1 -1 -2 -2 -1所以位于(i,j)的马可以走到新位置是在棋盘范围内的(i+ Htry1[h],j+Htry2[h]),其中h的取值是0~7.整个问题,我们可以用两种算法来解决,既“回溯算法”与“贪心算法”我们先来看回溯算法:搜索空间是整个棋盘上的8*8个点.约束条件是不出边界且每个点只能经过一次.搜索过程是从一点(i,j)出发,按深度有限的原则,从8个方向中尝试一个可以走的点,直到走过棋盘上所有的点.当没有点可达且没有遍历完棋盘时,就要撤销该点,从该点上一点开始找出另外的一个可达点,直到遍历完整个棋盘我们接着看程序的需求分析:1.输入的形式和输入值的范围;分开输入马的初始行坐标X和列坐标Y,X和Y的范围都是[0,7]。

C++ 数据结构课程设计 马踏棋局文档

C++ 数据结构课程设计 马踏棋局文档

课程设计题目1 问题描述将马随机放在国际象棋的8*8棋盘Board[8][8]的某个方格中,马按走棋规则进行移动,要求每个方格上只进入一次,走遍棋盘上全部64个方格2 基本要求(1)采用图形界面实现该游戏。

(2)从键盘输入马的初始位置。

(3)编制程序,求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入一个8* 8的方阵,并输出之。

3系统分析与设计3.1 数据结构逻辑结构为线性结构,用顺序栈。

坐标点用已结构体来表示,并将其的位置放在s[step]的栈中,而且将每走一步的坐标放在另一栈s1中3.2 算法设计1.程序框架及功能模块划分:2.设计功能的分析与实现void exit(point p)参数:point功能:计算出下一步可能位置,按其各个位置下一个位置的和压栈到s[]中算法描述:接受参数传来的值,按次序加上int horizontal[]={2,1,-1,-2,-2,-1,1,2};int vertical[]={-1,-2,-2,-1,1,2,2,1};再根据legal函数来判断是否合法(x(0~7),y(0~7))是,则保存在point ap[]中,再按各自下一步的数目从大到小排序。

最后,将ap[]中的点压栈。

int number(point p)参数:point功能:找出当前位置下一步的各种可能位置,计算可能之和算法描述:接受参数传来的值,按次序加上int horizontal[]={2,1,-1,-2,-2,-1,1,2};int vertical[]={-1,-2,-2,-1,1,2,2,1};再根据legal函数来判断是否合法(x(0~7),y(0~7))是,则加1并将值返回void next(point p)参数:point功能:/找出各个位置并将其步数记录算法描述:将其步数记录在board[][]的相应位置,并将这点压栈到s1,判断步数是否小于64,再根据这四个条件选择执行其中的一个,再递归调用next.bool legal(point p)参数:point功能:判断是否可行,合法(是否在棋盘上,是否走过)算法描述:用这样的语句if((p.x>=0)&&(p.x<n)&&(p.y<n)&&(p.y>=0)&&(bo ard[p.x][p.y]==0))return true;elsereturn false;4 测试数据及结果测试数据和运行输出及结果分析输入x(0-7),y(0-7)0 01 34 3 18 49 32 13 164 19 56 33 14 17 50 3157 2 35 48 55 52 15 1220 5 60 53 36 47 30 5141 58 37 46 61 54 11 266 21 42 59 38 27 64 2943 40 23 8 45 62 25 1022 7 44 39 24 9 28 63 Press any key to continue输入x(0-7),y(0-7)0 9输入不合法,重输入!输入x(0-7!),y(0-7!)4 530 27 10 49 40 25 8 511 48 29 26 9 6 39 2428 31 56 45 50 41 4 747 12 51 42 19 44 23 3832 57 46 55 52 1 18 313 64 53 60 43 20 37 2258 33 62 15 54 35 2 1763 14 59 34 61 16 21 36 Press any key to continue5 总结调试过程中遇到的主要问题,是如何解决的;问题1:只走到63步原因:第64步就走完了,并且s[62]中只有一个元素,这个判断条件(s[step].base==s[step].top&&number(p2)==0)满足就进入了,而始终不能走完解决方法:改了判断条件,改为((s[step].base==s[step].top&&number(p2)==0)&&step!=n* n-1)解决方案:用InitStack(s1)初始化问题3:冒泡排序超出边界原因:循环次数大解决方案:减少循环次数看了其他同学,都差不多,我已经按马的下一位置最难的先走,再走难度次之的位置。

马踏棋盘的实习报告

马踏棋盘的实习报告

马踏棋盘的实习报告实习报告:马踏棋盘一、实习单位及实习岗位简介实习单位:ABC软件公司实习岗位:算法工程师助理二、实习内容和任务作为算法工程师助理,我的主要任务是协助开发团队完成一个名为“马踏棋盘”的小游戏的设计和实现。

该游戏是基于棋盘上的骑士的移动规则进行设计的。

具体任务及完成情况如下:1.学习和理解“马踏棋盘”游戏的规则。

在开始设计游戏之前,首先需要深入了解和理解“马踏棋盘”的规则。

通过查阅相关资料和与开发团队成员的讨论,我对游戏规则有了初步的认识和理解。

2.设计游戏的棋盘和角色。

根据游戏规则的要求,我与开发团队成员一起设计和绘制了游戏的棋盘和角色。

棋盘采用8*8的方格,并且在其中的随机位置放置了一些障碍物,增加游戏的难度和挑战性。

角色则是一个具有代表骑士的形象的图标。

3.实现骑士的移动和规则判断。

在游戏中,骑士可以根据特定的移动规则在棋盘上移动。

根据游戏规则的要求,我编写了相应的算法,实现了骑士的移动和规则判断的功能。

通过这个功能,用户可以通过点击棋盘上的方格,移动骑士来完成游戏的目标。

4.添加游戏的界面和交互。

除了基本的游戏功能以外,我们还为游戏设计了用户友好的界面和交互。

通过游戏界面,用户可以清楚地看到棋盘和角色的位置,并且可以通过点击方格或者使用方向键来控制骑士的移动。

同时,我们还添加了计时器和得分系统,提升了游戏的趣味性和挑战性。

5.进行游戏的测试和优化。

为了确保游戏的稳定性和良好的体验效果,我们进行了多轮的测试和优化。

通过不断地发现和修复bug,我们最终完成了一个可以正常运行、界面友好、操作流畅的游戏。

三、实习收获和体会在这次实习中,我通过与开发团队的合作,深入了解了算法在游戏开发中的应用。

通过参与“马踏棋盘”游戏的设计和实现,我不仅加深了对算法和数据结构的理解,在实践中熟悉了常用的算法编程技巧,还提升了团队协作和解决问题的能力。

通过这次实习,我深刻体会到了算法在实际项目中的重要性和应用价值。

马踏棋盘

马踏棋盘

课程设计报告-马踏棋盘题目:编制一个演示国际象棋中马踏棋盘的程序.一、需求分析1.问题描述:本程序中,将马随机放在国际象棋的8×8棋盘Board[8][8]的某个方格中,马按走棋规则进行移动。

要求每个方格只进入一次,走遍棋盘上全部64个方格。

求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入一个8×8的方阵,输出方格。

2. 程序功能:在计算机终端上显示"1指定位置;2随机;"两种选择方案.由用户在键盘上输入1,2,使计算机执行对应方案:将数字1,2, (64)次填入一个8×8的方阵,输出方格。

3. 测试数据(1)确定入口位置,判断x,y是否在1到8的范围内;(2)确定b[9],判断最小出口;二、概要设计为实现上述程序功能,应建立一个栈和两个数组。

为此,需要两个抽象数据类型:栈,数组。

1.栈的抽象数据类型定义为:ADT stack {数据对象:D={a i|a i∈ElemSet,i=1,2,...,n, n≥ 0}数据关系:Rl={<a i-1,a i>|a i-1,a i∈D,a i-1<a i, a i∈D, i=2,...,n} 约定a n 端为栈顶,a1端为栈底。

基本操作:InitStack(&S)操作结果:构造一个空栈S。

DestoryStack(&S)初始条件:栈S已存在。

操作结果:栈S被销毁。

ClearStack(&S)初始条件:栈S已存在。

操作结果:将S清空为空栈。

StackEmpty(S)初始条件:栈S已存在。

操作结果:若栈S为空栈,则返回TURE,否则FALSE。

StackLength(S)初始条件:栈S已存在。

操作结果:返回S的元素个数,即栈的长度。

GetTop(S,&e)初始条件:栈S已存在且非空。

操作结果:用e返回S的栈顶元素。

Push(&S,e)初始条件:栈S已存在。

马踏棋盘的实习报告

马踏棋盘的实习报告

马踏棋盘实习报告题目:设计一个国际象棋的马踏遍棋盘的演示程序班级:姓名:学号:完成日期:一.需求分析将马随机放在m*n棋盘Board[m][n]的某个方格中,马按国际象棋行棋的规则进行移动。

要求每个方格只行走一次,走遍棋盘上全部m*n个方格。

编写非递归程序,求出马的行走路线,并按求出的行走路线,将数字1, 2, . m*n依次填入-一个m*n的方阵中。

程序要求:在国际象棋8×8棋盘上面,按照国际象棋规则中马的行进规则,实现从任意初始位置,每个方格只进入一次,走遍棋盘上全部64个方格。

编制程序,求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入一个8×8的方阵,并输出它的行走路线。

输入:任意一个起始位置;输出:无重复踏遍棋盘的结果,以数字1-64表示行走路线。

二.概要设计棋盘可用二维数组表示,马踏棋盘问题可采用回溯法解题。

当马位于棋盘某-位置时,它有唯一坐标,根据国际象棋的规则,它 6 7有8个方向可跳,对每一方向逐探测,从中选择可行方向继续行棋,每一行棋坐标借助栈记录。

若8个方向均不可行则借助栈回溯,在前一位置选择下一可行方向继续行棋,直至跳足m*n步,此时成功的走步记录在栈中。

或不断回湖直至栈空失败。

关于栈的抽象数据类型定义:否则返回ERRORPushStack( &s,SElemType e);操作结果:插入元素e为新的栈顶元素PopStack (&s,SElemType &e);操作结果:若栈不空,则删除s的栈顶元素,并用e返回其值,并返回OK;否则返回ERROR本程序包含以下模块:主程序模块:void main(){定义变量;接受命令;处理命令;退出;}起始坐标函数模块——马儿在棋盘上的起始位置;搜索路径函数模块——马儿每个方向进行尝试,直到试完整个棋盘;输出路径函数模块——输出马儿行走的路径模块调用关系:函数调用关系:三.详细设计#define OK 1#define TRUE 1#define ERROR 0#define FALSE 0#define M 8#define N 8int direction[2][9]={{0,-2,-1,1,2,2,1,-1,-2},{0,1,2,2,1,-1,-2,-2,-1}}; //增量数组int pow[M][N];int check[M][N],next[M][N]; //创建棋盘,初始为0struct Element //数据域{int x,y; //x行,y列int d; //下一步的方向};typedef struct LStack //链栈}*PLStack;typedef struct check //定义棋盘内点的坐标{int x;int y;}Check;/*************栈函数****************/ int InitStack(PLStack &S)//构造空栈{S=NULL;return OK;}int StackEmpty(PLStack S)//判断栈是否为空{if(S==NULL)return OK;elsereturn FALSE;}int Push(PLStack &S, Element e)//元素入栈PLStack p;p=(PLStack)malloc(sizeof(LStack));p->data=e;p->next=S;S=p;return OK;}int Pop(PLStack &S,Element &e) //元素出栈{PLStack p;if(!StackEmpty(S)){e=S->data;p=S;S=S->next;free(p);return OK;}/********贪心权值函数********/void Printf(int p[M][N]){ //打印权值数组for(int i=0;i<M;i++){for(int j=0;j<N;j++)printf(" %2d ",p[i][j]);printf("\n");}}void InitWeight(){ //创建权值数组并初始化每个位置的权值for(int i=0;i<M;i++)for(int j=0;j<N;j++)pow[i][j]=0;for(int i=0;i<M;i++){for(int j=0;j<N;j++){for(int dir=1;dir<=8;dir++){int x1=i+direction[0][dir];int y1=j+direction[1][dir];if(x1>=0&&x1<=7&&y1>=0&&y1<=7)pow[i][j]++;}}}}void SetWeight(int x,int y) { //位置(x,y)设置为被占用时,修改权值数组,被占用时为9pow[x][y]=9;for(int dir=1;dir<=8;dir++){int x1=x+direction[0][dir];int y1=y+direction[1][dir];if(x1>=0&&x1<=7&&y1>=0&&y1<=7&& pow[x1][y1]!=9)pow[x1][y1]--;}}void UnSetWeight(int x,int y){ //位置(x,y)设置为未占用时,修改权值数组for(int dir=1;dir<=8;dir++){ int x1=x+direction[0][dir];struct Element t,data;int pow_min=9;for(int dir=1;dir<=8;dir++){ //探测下一步可走的方向int x1=x+direction[0][dir];int y1=y+direction[1][dir];if(x1>=0&&x1<=7&&y1>=0&&y1<=7&& pow[x1][y1]!=9){if(pow_min>pow[x1][y1])//找出下一步位置中权值最小的{pow_min=pow[x1][y1];t.d=dir; //上一步的方向t.x=x1;t.y=y1;}}}data.x=x; //入栈data.y=y;data.d=t.d;Push(H,data);x=t.x; //坐标更新y=t.y;i++; //步数增加}PLStack H;InitStack(H);Check start;printf("请输入起始坐标x y:");scanf("%d%d",&start.x,&start.y);Step(start,H);Printf(check);return 0;}四.调试分析1.刚开始的时候并没有采用贪心算法,时间复杂度很大,探测量也很大。

棋盘算法实验报告(3篇)

棋盘算法实验报告(3篇)

个人自我介绍简单大方
很抱歉,但我无法为您提供____字的自我介绍。

以下是一个简洁而大方的自我介绍示例,供您参考:
大家好,我叫[姓名]。

很高兴有机会向大家介绍一下自己。

我出生并长大在[所在地],是一个勤奋、积极向上的人。

在学业方面,我于[毕业时间]从[学校名称]获得了[学位/专业]学位。

在大学期间,我通过自我努力和课外学习,取得了良好的学术成绩,并参与了一些学生组织和社团活动。

这些经历不仅培养了我的团队合作和领导能力,也加强了我的沟通和组织能力。

在工作方面,我有[工作年限]年的相关工作经验。

我曾在[公司/组织名称]担任[职位],负责[工作职责]。

在这期间,我不断努力提升自己的专业知识和技能,以适应快速发展的工作环境。

我善于分析问题并找出解决方案,能够有效地与团队合作并承担责任,这些都为我赢得了同事和上级的认可。

除了工作,我也积极参与志愿者活动,希望能为社区和弱势群体做一点贡献。

我相信,通过奉献和关心他人,我们可以建立一个更加和谐和温暖的社会。

在个人生活中,我喜欢阅读、旅行和运动。

阅读扩展了我的视野,旅行让我能够体验不同的文化和风景,而运动则让我保持健康和积极的精神状态。

此外,我也很喜欢与家人和朋友相处,分享彼此的喜怒哀乐。

总的来说,我是一个热情、乐观、有责任心的人。

我相信勤奋和坚持可以取得成功,而真诚和善良可以赢得他人的信任和支持。

我希望能够在您的团队中发挥我的才能,并与大家一同成长和进步。

这就是我简单的自我介绍,谢谢大家!。

马踏棋盘 数据结构实践报告

马踏棋盘 数据结构实践报告

马踏棋盘问题摘要:马踏棋盘就是在国际象棋8X8棋盘上面,按照国际象棋规则中马的行进规则,实现从任意初始位置,每个方格只进入一次,走遍棋盘上全部64个方格。

理解栈的“后进先出”的特性以及学会使用回溯。

关键字:马踏棋盘、递归、栈、回溯1.引言马踏棋盘就是在国际象棋8X8棋盘上面,按照国际象棋规则中马的行进规则,实现从任意初始位置,每个方格只进入一次,走遍棋盘上全部64个方格。

编制程序,求出马的行走路线,并按求出的行走路线,将数字1,2….64依次填入一个8X8的方阵,并输出它的行走路线。

输入:任意一个起始位置;输出:无重复踏遍棋盘的结果,以数字1-64表示行走路线。

2.需求分析(1)需要输出一个8X8的棋盘,可以采用二维数组的方法实现。

(2)输入马的起始位置,必须保证输入的数字在规定范围内,即0<=X<=7,0<=Y<=7。

(3)保证马能走遍整个棋盘,并且不重复。

(4)在棋盘上输出马的行走路线,标记好数字1、2、3直到64。

3.数据结构设计采用栈数组为存储结构。

#define maxsize 100struct{int i;int j;int director;}stack[maxsize];4.算法设计4.1 马的起始坐标void location(int x,int y) //马的位置坐标的初始化{top++;stack[top].i=x; //起始位置的横坐标进栈stack[top].j=y; //起始位置的竖坐标进栈stack[top].director=-1;a[x][y]=top+1; //标记棋盘Try(x,y); //探寻的马的行走路线}4.2 路径探寻函数void Try(int i,int j){ int count,find,min,director;int i1,j1,h,k,s;intb[8]={-2,-2,-1,1,2,2,1,-1},c[8]={1,-1,-2,-2,-1,1,2,2};//存储马各个出口相对当前位置行、列坐标的增量数组int b2[8],b1[8];for(h=0;h<=7;h++)//用数组b1[8]记录当前位置的下一个位置的可行路径的条数{ count=0;i=stack[top].i+c[h];j=stack[top].j+b[h];if(i>=0&&i<=7&&j>=0&&j<=7&&a[i][j]==0)//如果找到下一个位置{for(k=0;k<=7;k++){i1=i+c[k];j1=j+b[k];if(i1>=0&&i1<=7&&j1>=0&&j1<=7&&a[i1][j1]==0) //如果找到下一个位置count++; //记录条数}b1[h]=count; //将条数存入b1[8]中}}for(h=0;h<=7;h++)//根据可行路径条数的大小,从小到大排序,并放入数组b2[8]中{min=9;for(k=0;k<=7;k++)if(min>b1[k]){min=b1[k];b2[h]=k;s=k;}b1[s]=9;}find=0;director=stack[top].director;for(h=director+1;h<=7;h++)//向8个方向进行寻找{i=stack[top].i+c[b2[h]];j=stack[top].j+b[b2[h]];if(i>=0&&i<=7&&j>=0&&j<=7&&a[i][j]==0){stack[top].director=h; //存储栈的寻找方向top++; //进栈stack[top].i=i;stack[top].j=j;stack[top].director=-1;//重新初始化下一栈的方向a[i][j]=top+1;find=1; //找到下一位置break;}}if(find!=1){a[stack[top].i][stack[top].j]=0; //清除棋盘的标记top--; //退栈}if(top<63)Try(i,j); //递归}4.3输出函数void display(){int i,j;for(i=0;i<=7;i++){ for(j=0;j<=7;j++)printf("\t%d ",a[i][j]); //输出马的行走路线printf("\n\n");}printf("\n");}5.程序实现5.1 主函数void main(){int i,j,x,y;for(i=0;i<=7;i++) //棋盘的初始化for(j=0;j<=7;j++)a[i][j]=0;printf("输入X Y (0=<X<=7,0=<Y<=7)\n");scanf("%d%d",&x,&y);if(x>=0&&x<=7&&y>=0&&y<=7)//判断输入的起始位子是否正确{location(x,y);display();}else printf("错误\n");}5.2运行结果(1)当输入不符合要求时(2)正确输入时5.3 算法分析(1)马的起始坐标一开始先建立一个栈数组,里面包括横坐标和竖坐标还有方向。

数据结构课程设计 马踏棋盘分解

数据结构课程设计 马踏棋盘分解

杭州师范大学钱江学院课程设计2013 年12 月21 日目录一.概述 (3)二.总体方案设计 (3)三.详细设计 (4)四.最终输出 (6)五.课程设计总结 (10)参考文献 (13)一概述1.课程设计的目的(1)课题描述设计一个国际象棋的马踏遍棋盘的演示程序。

(2)课题意义通过“马踏棋盘”算法的研究,强化了个人对“栈”数据结构的定义和运用,同时也锻炼了自身的C语言编程能力。

另一方面,通过对“马踏棋盘” 算法的研究,个人对“迷宫”、“棋盘遍历”一类的问题,有了深刻的认识,为今后解决以此问题为基础的相关的问题,打下了坚实的基础。

(3)解决问题的关键点说明解决问题的关键首先要熟练掌握 C语言编程技术,同时能够熟练运用“栈”数据结构。

另外,态度也是非常重要的。

在课程设计过程中,难免会遇到困难,但是不能轻易放弃,要肯花时间,能静得下心,积极查阅相关资料,积极与指导老师沟通。

2.课程设计的要求(1)课题设计要求将马随机放在国际象棋的8X 8棋盘Board[0〜7][0〜7]的某个方格中,马按走棋规则进行移动。

要求每个方格只进入一次,走遍棋盘上全部64个方格。

编制非递归程序,求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入一个8X 8的方阵,输出之。

程序由回溯法和贪心法实现,比较两种算法的时间复杂度。

(2)课题设计的思路首先,搞清楚马每次在棋盘上有 8个方向可走,定义两个一位数组,来存储马下一着点的水平和纵向偏移量。

程序再定义一个8*8二维数组,初始所有元素置0,起始点元素置1。

若为回溯法,初始方向数据(一维数组下标) 入栈。

随后,马从起始点开始,每次首先寻找下一可行的着点,然后记下方向,方向数据入栈,把该位置元素置为合适的序列号,若无下一可行着点,则回溯,寻找下一方向位置着点,以此类推,直到 64填入数组中,则输出二维数组,即为马可走的方案。

若为贪婪法,选择下一出口的贪婪标准是在那些允许走的位置中,选择出口最少的那个位置。

实验报告马踏棋盘

实验报告马踏棋盘

2.4题马踏棋盘题目:设计一个国际象棋的马踏棋盘的演示程序班级::学号:完成日期:一.需求分析(1)输入的形式和输入值的围:输入马的初始行坐标X和列坐标Y,X和Y的围都是[1,8]。

(2)输出形式:以数组下表的形式输入,i为行标,j为列标,用空格符号隔开。

以棋盘形式输出,每一格打印马走的步数,这种方式比较直观(3)程序所能达到的功能:让马从任意起点出发都能够遍历整个8*8的棋盘。

(4)测试数据,包括正确输入及输出结果和含有错误的输入及其输出结果。

数据可以任定,只要1<=x,y<=8就可以了。

正确的输出结果为一个二维数组,每个元素的值表示马行走的第几步,若输入有错,则程序会显示:“输入有误!请重新输入……”并且要求用户重新输入数据,直至输入正确为止。

二.概要设计(1)、位置的存储表示方式(2) typedef struct {int x;int y;int from;}Point;(2)、栈的存储方式#define STACKSIZE 70#define STACKINCREASE 10typedef struct Stack {Point *top;Point *base;int stacksize;};(1)、设定栈的抽象数据类型定义: ADT Stack {数据对象:D={ai | ai∈ElemSet,i=1,2,…,n,n≥0}数据关系:R1={<ai-1 , ai>|ai-1, ai∈D,i=2,…,n} 约定an端为栈顶,ai端为栈顶。

基本操作:InitStack(&s)操作结果:构造一个空栈s,DestroyStack(&s)初始条件:栈s已存在。

操作结果:栈s被销毁。

ClearStack(&s)初始条件:栈s已存在。

操作结果:栈s清为空栈。

StackEmpty(&s)初始条件:栈s已存在。

操作结果:若栈s为空栈,则返回TRUE,否则返回FALSE。

马踏棋盘课程设计实验报告

马踏棋盘课程设计实验报告

马踏棋盘课程设计实验报告《数据结构》课程设计实验报告课程名称: 《数据结构》课程设计课程设计题目: 马踏棋盘姓名: 邱可昉院系: 计算机学院专业: 计算机科学与技术班级: 10052313 学号: 10051319 指导老师: 王立波2012年5月18日1目录1.课程设计的目的...............................................................3 2.问题分析........................................................................3 3.课程设计报告内容 (3)(1)概要设计 (3)(2)详细设计 (3)(3)测试结果 (5)(4)程序清单...............................................................6 4.个人小结 (10)21.课程设计的目的《数据结构》是计算机软件的一门基础课程,计算机科学各领域及有关的应用软件都要用到各种类型的数据结构。

学好数据结构对掌握实际编程能力是很有帮助的。

为了学好《数据结构》,必须编写一些在特定数据结构上的算法,通过上机调试,才能更好地掌握各种数据结构及其特点,同时提高解决计算机应用实际问题的能力。

2.问题分析*问题描述:将马随机放在国际象棋的8X8棋盘Bo阿rd[0..7,0..7]的某个方格中,马按走棋规则进行移动。

要求每个方格上只进入一次,走遍棋盘上全部64个方格。

编制非递归程序,求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入8X8的方阵输出之。

*测试数据:由读者指定,可自行指定一个马的初始位置。

*实现提示:每次在多个可走位置中选择一个进行试探,其余未曾试探过的可走位置必须用适当结构妥善管理,以备试探失败时的“回溯”(悔棋)使用。

并探讨每次选择位置的“最佳策略”,以减少回溯的次数。

数据结构课程设计(马踏棋盘)

数据结构课程设计(马踏棋盘)

中南民族大学数据结构课程设计报告姓名:康宇年级: 2010学号: 10061014专业:计算机科学与技术指导老师:宋中山2013年4月15日实习报告:2.4题 马踏棋盘题目:设计一个国际象棋的马踏棋盘的演示程序班级:计科一班 姓名:康宇 学号:10061014 完成日期:2013.4.15 一、需求分析1、国际象棋的马踏棋盘的功能是:将马随机放在国际象棋的N*N 棋盘board[N][N]的某个方格中,马按走棋规则进行移动。

要求每个方格只进一次,走遍棋盘上全部N*N 个方格。

编制非递归程序,求出马的行走路线,并按求出的行走路线,将数字1,2,...,N*N 依次填入一个N*N 的方阵,输出之。

2、测试数据:N 由读者指定。

马开始的位置也有读者指定(x,y ),1<=x<=N,1<=y<=N.3、实现提示:下图显示了N 为6,马位于方格(3,3),8个可能的移动位置。

一般来说,马位于位置(x ,y )时,可以走到下列8个位置之一。

但是,如果(x,y )靠近棋盘的边缘,上述有些位置可能超出棋盘范围,成为不允许的位置。

8个可能的位置可以用两个一维数组hi[0...7],hj[0...7]来表示:1 2 3 4 5 6二、概要设计为实现上述程序功能,应用栈Stack[Max*Max]来表示棋盘的行和列。

定义棋盘的规格N,马在下一步可以走的8个位置,hi[0...7],hj[0...7],用数组board[Max][Max]来标记棋盘,top 标记栈指针。

用户在输入了期盼的规格和起始坐标后,程序通过八个方向的探寻,123456输出第一个符合要求的棋盘,棋盘上显示了马每一步的位置,每一个位置只踏了一次,且踏遍棋盘。

1、元素类型(栈):struct Stack{int i; //行坐标int j; //列坐标} stack[Max][ Max];2、建立三个全局位置数组:int hi[8]={-2,-1,1,2,2,1,-1,-2};int hj[8]={1,2,2,1,-1,-2,-2,-1};用来存放下一个可能位置的横纵坐标;int board[Max][Max];用来标记棋盘。

马踏棋盘——一个数据结构综合实验案例新解

马踏棋盘——一个数据结构综合实验案例新解
生 容 易 下 手 ,容 易 通 过 对 已学 理 论 举 一 反 三 ,进 行 求 解 。 传 统 的马 踏 棋 盘 问题 采 用 的 回 溯 法 或 者 贪 心 法 求 解 , 学 生 学 完 了数 据 结 构 课 程 ,用 此 类 方 法 求 解 仍 具 有 一 定 难 度 。 就 其 原 因 , 学 生 对 数 据 结构 的 理 论 知 识 不 能 灵 活 运 用 以及 相
总第 1 4卷 1 7期 5 21 0 2年 9月
大 众 科 技
P uar in e & Te h oo y op l e c Sc c n lg
Vo . 4 N0 9 L1 .
Se t pemb r 2 1 e 0 2
马踏 棋 盘
一 个 数 据 结构 综 合 实验 案 例 新解
知从 何 下 手 ,产 生 畏 难 心 理 ,会 打 击 学 生解 决 问题 的 自信 心 ;
而 案 例 过 于 简 单 , 则 达 不 到 综 合 实验 要 求 ,起 不 到锻 炼 学 生 的 目的 。一 个 合 适 的 综 合 实 验 案 例 ,应 该具 有 以 下几 个 特 点 :
课程打 下坚 实的基础 。然而 , 数据 结构也是一门理论性很强 的课程 ,理论 知识抽象 、概 念多 、算法 多而杂 ,学 生不好理 解 ,设 计程序无 从下手 。很 多学生反 映这 门课 “ 难懂 、不好 用 ”。学生不通 过实践很难对其 理论有深入 理解和应用 。因
Ab t a t I h sp p r t ep o lm f o s r v l g o h s b ad wa n r d c d i t a a s u t r x e me t e c i g a n s r c : n t i a e , h r b e o r eta ei n c e s o r si to u e n o d t t c u ee p r h n r i n a h n sa t

马踏棋盘的实习报告

马踏棋盘的实习报告

马踏棋盘实习报告题目:设计一个国际象棋的马踏遍棋盘的演示程序班级:姓名:学号:完成日期:一.需求分析将马随机放在m*n棋盘Board[m][n]的某个方格中,马按国际象棋行棋的规则进行移动。

要求每个方格只行走一次,走遍棋盘上全部m*n个方格。

编写非递归程序,求出马的行走路线,并按求出的行走路线,将数字1, 2, . m*n依次填入-一个m*n的方阵中。

程序要求:在国际象棋8×8棋盘上面,按照国际象棋规则中马的行进规则,实现从任意初始位置,每个方格只进入一次,走遍棋盘上全部64个方格。

编制程序,求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入一个8×8的方阵,并输出它的行走路线。

输入:任意一个起始位置;输出:无重复踏遍棋盘的结果,以数字1-64表示行走路线。

二.概要设计棋盘可用二维数组表示,马踏棋盘问题可采用回溯法解题。

当马位于棋盘某-位置时,它有唯一坐标,根据国际象棋的规则,它 6 7有8个方向可跳,对每一方向逐探测,从中选择可行方向继续行棋,每一行棋坐标借助栈记录。

若8个方向均不可行则借助栈回溯,在前一位置选择下一可行方向继续行棋,直至跳足m*n步,此时成功的走步记录在栈中。

或不断回湖直至栈空失败。

关于栈的抽象数据类型定义:否则返回ERRORPushStack( &s,SElemType e);操作结果:插入元素e为新的栈顶元素PopStack (&s,SElemType &e);操作结果:若栈不空,则删除s的栈顶元素,并用e返回其值,并返回OK;否则返回ERROR本程序包含以下模块:主程序模块:void main(){定义变量;接受命令;处理命令;退出;}起始坐标函数模块——马儿在棋盘上的起始位置;搜索路径函数模块——马儿每个方向进行尝试,直到试完整个棋盘;输出路径函数模块——输出马儿行走的路径模块调用关系:函数调用关系:三.详细设计#define OK 1#define TRUE 1#define ERROR 0#define FALSE 0#define M 8#define N 8int direction[2][9]={{0,-2,-1,1,2,2,1,-1,-2},{0,1,2,2,1,-1,-2,-2,-1}}; //增量数组int pow[M][N];int check[M][N],next[M][N]; //创建棋盘,初始为0struct Element //数据域{int x,y; //x行,y列int d; //下一步的方向};typedef struct LStack //链栈}*PLStack;typedef struct check //定义棋盘内点的坐标{int x;int y;}Check;/*************栈函数****************/ int InitStack(PLStack &S)//构造空栈{S=NULL;return OK;}int StackEmpty(PLStack S)//判断栈是否为空{if(S==NULL)return OK;elsereturn FALSE;}int Push(PLStack &S, Element e)//元素入栈PLStack p;p=(PLStack)malloc(sizeof(LStack));p->data=e;p->next=S;S=p;return OK;}int Pop(PLStack &S,Element &e) //元素出栈{PLStack p;if(!StackEmpty(S)){e=S->data;p=S;S=S->next;free(p);return OK;}/********贪心权值函数********/void Printf(int p[M][N]){ //打印权值数组for(int i=0;i<M;i++){for(int j=0;j<N;j++)printf(" %2d ",p[i][j]);printf("\n");}}void InitWeight(){ //创建权值数组并初始化每个位置的权值for(int i=0;i<M;i++)for(int j=0;j<N;j++)pow[i][j]=0;for(int i=0;i<M;i++){for(int j=0;j<N;j++){for(int dir=1;dir<=8;dir++){int x1=i+direction[0][dir];int y1=j+direction[1][dir];if(x1>=0&&x1<=7&&y1>=0&&y1<=7)pow[i][j]++;}}}}void SetWeight(int x,int y) { //位置(x,y)设置为被占用时,修改权值数组,被占用时为9pow[x][y]=9;for(int dir=1;dir<=8;dir++){int x1=x+direction[0][dir];int y1=y+direction[1][dir];if(x1>=0&&x1<=7&&y1>=0&&y1<=7&& pow[x1][y1]!=9)pow[x1][y1]--;}}void UnSetWeight(int x,int y){ //位置(x,y)设置为未占用时,修改权值数组for(int dir=1;dir<=8;dir++){ int x1=x+direction[0][dir];struct Element t,data;int pow_min=9;for(int dir=1;dir<=8;dir++){ //探测下一步可走的方向int x1=x+direction[0][dir];int y1=y+direction[1][dir];if(x1>=0&&x1<=7&&y1>=0&&y1<=7&& pow[x1][y1]!=9){if(pow_min>pow[x1][y1])//找出下一步位置中权值最小的{pow_min=pow[x1][y1];t.d=dir; //上一步的方向t.x=x1;t.y=y1;}}}data.x=x; //入栈data.y=y;data.d=t.d;Push(H,data);x=t.x; //坐标更新y=t.y;i++; //步数增加}PLStack H;InitStack(H);Check start;printf("请输入起始坐标x y:");scanf("%d%d",&start.x,&start.y);Step(start,H);Printf(check);return 0;}四.调试分析1.刚开始的时候并没有采用贪心算法,时间复杂度很大,探测量也很大。

1实验题目马踏棋盘

1实验题目马踏棋盘

1:实验题目:马踏棋盘,2:实验目的:队列和栈的操作练习:3:实验具体内容:设计一个国际象棋的马踏遍棋盘的演示程序。

将马随机放在国际象棋8x8棋盘Board[8][8]的某个方格中,马按走棋规则进行移动。

要求每个方格只进入一次,走遍棋盘上全部64个方格。

编制非递归程序,求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入一个8x8的方阵,输出之。

矚慫润厲钐瘗睞枥庑赖賃軔。

4:数据结构算法思想:数据结构:简单的结构体和相关数组;算法思想:a :首先定义一个8*8的数组用于存放马的跳步过程;定义方向结点;b :获得马的第一个踩入点,调用findway()函数,该函数的while()语句将获得下一个要踩入的结点坐标,该过程调用pathnum()函数(注解:该函数给出了可踩入的所有结点各自的路径数目); 在findway()中,选择的要进入的下一个结点就是在pathway()中找到的结点(注解:该结点是可跳入的所有结的中路径最少的一个);聞創沟燴鐺險爱氇谴净祸測。

c : 在每步踩入前,将该结点的下标和踩入的次序做记录并输出;d : 读取最后一个结点的相关信息;5:模块划分:6:详细设计及运行结果:A:定义一个8*8的数组,用于存放每次踩入的结点位置;B:获取第一个踩入点;C:调用findway()函数Findway() 函数功能介绍:定义一个结点类型数组,用于存放8个下一步可踩入结点的信息;期间调用pathnum() 函数,该函数功能是记录所有下一个可踩入结点的可执行路径数目);选择下一个结点中路径最少的结点为下一个踩入的结点;在进入下一个踩入点前,先保存该结点的信息并输出,然后依次寻找下一个结点;残骛楼諍锩瀨濟溆塹籟婭骒。

D:寻找最后一个结点,并赋给相应信息;运行结果如下:7:调试情况,设计技巧和相关方法:A : 该开始想着利用栈的数据结构,记录回溯的相关信息,后来查资料发现如果每次入结点路径最少的那个结点,根本不会产生回溯的过程,后来就省去了栈队列的应用;酽锕极額閉镇桧猪訣锥顧荭。

马跳棋盘问题

马跳棋盘问题

用贪婪算法优化马踏棋盘问题一、问题阐述将马放到国际象棋的8*8棋盘board上的某个方格中,马按走棋规则进行移动,要求每个方格进入且只进入一次,走遍棋盘上的64个方格,将数字1,2,3…,64依次填入一个8*8的方阵,找出一种可行的方案,并用贪婪算法进行优化。

0 1 2 3 4 5 6 7如图所示,当马在棋盘位置(4,3)时,它可以有1,2,3,4,5,6,7,8个位置可跳二、解题思路1.需求分析棋盘可以看做一个矩阵,当马位于棋盘上某一位置时,它就有一个唯一的坐标,那么根据国际象棋的规则,它有8个位置可以跳,这8个位置的坐标是和当前马的坐标是有联系的,例如马的坐标是(x,y),那么它的下一跳的位置可以是(x-1,y-2)。

当然坐标不能越界。

马所在的当前位置标为1,它的下一跳的位置标为2,在下一跳的位置标为3,依次类推,如果马走完棋盘,那么最后在棋盘上标的位置是64。

2.解决方案(1)回溯法我们可以采用回溯法求解,当马在当前位置时,我们将它下一跳的所有位置保存,然后从中选择一个位置作为当前位置在跳,递归下去,如果跳不下去,回溯。

这有点类似图的深度搜索。

(2)贪婪法贪婪算法是指,在对问题求解时,总是做出在当前看来是最好的选择。

也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。

那么我们在回溯法的基础上,用贪婪算法进行优化,在选择下一跳的位置时,总是选择出口少的那个位置,这里出口少是指这个位置的下一跳位置个数少。

这是一种局部调整最优的做法,如果优先选择出口多的子结点,那出口少的子结点就会越来越多,很可能出现‘死’结点,这样对下面的搜索纯粹是徒劳,这样会浪费很多无用的时间,反过来如果每次都优先选择出口少的结点跳,那出口少的结点就会越来越少,这样跳成功的机会就更大一些。

三、编写代码#include <iostream>#include <fstream>#include <ctime>#include <cstdlib>#include <queue>#include <vector>using namespace std;class Point{protected:int x;int y;public:Point(int X=0,int Y=0):x(X),y(Y){}Point(const Point& P){x=P.x;y=P.y;}Point& operator=(const Point& P){x=P.x;y=P.y;return *this;}int getX() const{return x;}int getY() const{return y;}void setX(int X){x=X;}void setY(int Y){y=Y;}};class PointX:public Point{private:int cnt_NextJump; //当马以当前位置为基准,下一跳位置的个数public:PointX(int X=0,int Y=0,int cnt=0):Point(X,Y){}PointX(const PointX& p){x=p.x;y=p.y;cnt_NextJump=t_NextJump;}PointX& operator=(const PointX& p){x=p.x;y=p.y;cnt_NextJump=t_NextJump;return *this;}int getCnt() const{return cnt_NextJump;}void setCnt(int cnt){cnt_NextJump=cnt;}};const int N=8;int offsetX[N]={-1,1,-1,1,-2,-2,2,2}; //相对于当前点马的下一落脚点x 的偏移量int offsetY[N]={-2,-2,2,2,-1,1,-1,1}; //相对于当前点马的下一落脚点y 的偏移量ofstream file1; //文件输出流class SearchPath //寻径类{protected:int chessboard[N][N]; //棋盘Point startPoint; //起始点bool find; //find=false表示没有找到路径int RecursiveDepth; //递归的深度bool JudgeNextJumpPoint(int x,int y) //判断下一跳的位置是否合法{//其中chessboard[x][y]==0表示马可以跳到(x,y)的位置if(x<N && x>=0 && y<N && y>=0 && chessboard[x][y]==0) return true;else return false;}void Solution(Point p,int count){if(find) return;RecursiveDepth++;int x,y;x=p.getX();y=p.getY();chessboard[x][y]=count;if(count>=N*N){find=true;Success(); //输出解}int i;queue<Point>Q;for(i=0;i<N;i++){Point candidatePoint(x+offsetX[i],y+offsetY[i]); //求出候选的点if(JudgeNextJumpPoint(candidatePoint.getX(),candidatePoint.getY()) ==false) continue; //判断候选点的合法性Q.push(candidatePoint); //如果合法入队列}while(Q.empty()==false) //当队列不空时{Point next=Q.front(); //取出队头元素Q.pop();Solution(next,count+1);chessboard[x][y]=0;//当Solution返回到此时说明上一步求出的候选点没有子候选点,所以讲此位置重新置为0}}void Success(){int i,j;for(i=0;i<N;i++){for(j=0;j<N;j++) file1<<chessboard[i][j]<<" ";file1<<endl;}}public:SearchPath(const Point& s){int i,j;for(i=0;i<N;i++) //初始化棋盘{for(j=0;j<N;j++) chessboard[i][j]=0;}if(JudgeNextJumpPoint(s.getX(),s.getY())==false){cerr<<"输入点的位置非法!"<<endl;exit(1);}RecursiveDepth=0;find=false;startPoint=s;}void Solution(){int count=1;Solution(startPoint,count);}int getRecursiveDepth() const{return RecursiveDepth;}};ofstream file2;class Greedy_SearchPath:public SearchPath {private:void Success(){int i,j;for(i=0;i<N;i++){for(j=0;j<N;j++) file2<<chessboard[i][j]<<" ";file2<<endl;}}void SetNextJumpCnt(PointX& p) //设置点p位置下一跳的个数{int cnt=0;int i;int x=p.getX();int y=p.getY();for(i=0;i<N;i++){PointX candidatePoint(x+offsetX[i],y+offsetY[i],0); //求出候选的点if(JudgeNextJumpPoint(candidatePoint.getX(),candidatePoint.getY()) ==false) continue; //判断候选点的合法性cnt++;}p.setCnt(cnt);}void Solution(PointX p,int count){if(find) return;RecursiveDepth++;int x,y;x=p.getX();y=p.getY();chessboard[x][y]=count;if(count>=N*N){find=true;Success(); //输出解}int i;vector<PointX>v; //用向量去存储候选点for(i=0;i<N;i++){PointX candidatePoint(x+offsetX[i],y+offsetY[i],0); //求出候选的点if(JudgeNextJumpPoint(candidatePoint.getX(),candidatePoint.getY()) ==false) continue; //判断候选点的合法性SetNextJumpCnt(candidatePoint);v.push_back(candidatePoint); //如果合法加入向量}vector<PointX>::iterator it,min;int cnt=N+1;while(v.empty()==false) //当向量不空时{for(it=v.begin(),min=it;it!=v.end();it++) //查找下一跳个数最少的位置{if(it->getCnt()<cnt){cnt=it->getCnt();min=it;}}PointX next=*min; //取出元素v.erase(min);Solution(next,count+1);chessboard[x][y]=0;//当Solution返回到此时说明上一步求出的候选点没有子候选点,所以讲此位置重新置为0}}public:Greedy_SearchPath(const Point& s):SearchPath(s){}void Solution(){int count=1;PointX p(startPoint.getX(),startPoint.getY());Solution(p,count);}};void main(){int n=20;int i;int x,y;srand(unsigned(time(NULL)));file1.open("e:\\log1.txt");if(!file1) return;file2.open("e:\\log2.txt");if(!file2) return;for(i=0;i<n;i++){x=rand()%N;y=rand()%N;Point p(x,y);SearchPath s(p);Greedy_SearchPath ss(p);s.Solution();ss.Solution();file1<<s.getRecursiveDepth()<<endl;file2<<ss.getRecursiveDepth()<<endl;}}四、测试数据我们随机选择20个位置作为测试,分别用回溯法和贪婪法记录每次成功方案的递归深度,递归深度越少,性能越佳。

国际象棋马走满棋盘不重复

国际象棋马走满棋盘不重复
二 概要设计
为实现上述功能需要一个顺序的栈存储每一步,以及一个模拟马踏棋盘过程的模块。为 此需要两个抽象数据类型,即栈和马踏棋盘.
1.对栈的抽象数据定义为:
void InitStack(SqStack &S);
//构造一个空栈S
bool GetTop(SqStack &S,XY &e); //若栈不空,则用e返回s的栈顶元素,返回OK;
}
(*S.top).x=e.x;
//把 e 压入栈
(*S.top).y=e.y;
(*S.top).p=e.p;
S.top++;
}
bool Pop(SqStack &S){
if (S.top == S.base) return false;
//如果空栈返回 false
--S.top;
//删除栈顶元素
return true;
printf("
*程序说明:
*\n"); printf(" printf("
* 8X8 的国际棋盘 * 输入两个数字作为马的初始位置
*\n");
*\n"); printf(" printf("
* 输入数据必须在 0~7 之间 * 程序将给出马的遍历行走路线
*\n");
*\n"); printf("
* 路线以步数形式给出
*\n"); printf("
********************************计算机 2 班 16 组
*******\n\n"); printf("输入初始位置开始程序:");
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构课程设计题目:马踏棋盘院系:班级:学号:姓名:2014-2015年度第1学期马踏棋盘一.题目:马踏棋盘 (3)二. 设计目标 (3)三. 问题描述 (3)四. 需求分析 (4)五. 概要设计 (4)第一步:定义四个常量和一个数据类型 (4)第二步:构造函数 (4)六. 详细设计(给出算法的伪码描述和流程图) (5)流程图设计 (5)代码分析 (9)第一步:定义常量与变量 (9)第二步:构造函数 (9)●定义一个结构体类型 (9)●创建一个初始化函数 (10)●创建提示输入函数 (10)●创建产生新节点函数 (11)●创建计算路径函数 (12)●创建入栈函数 (13)●创建出栈函数 (13)●创建输出函数 (13)第三步:在主函数中调用其它函数 (15)七. 测试分析 (16)八. 使用说明 (16)九. 测试数据 (16)十.课程设计总结 (17)一.题目:马踏棋盘二. 设计目标帮助学生熟练掌握顺序栈的基本操作,让学生深入了解栈的使用,使得更深层次的灵活运用栈。

三. 问题描述○所谓的马踏棋盘是:将马随机放在国际象棋的8×8棋盘的某个方格中,马按走棋规则(马走日字)进行移动。

要求每个方格只进入一次,走遍棋盘上全部64个方格。

由用户自行指定一个马的初始位置,求出马的行走路线,并按照求出的行走路线的顺序,将数字1、2、…、64依次填入一个8X8的方阵并输出。

从用户给出的初始位置开始判断,按照顺时针顺序,每次产生一个新的路点,并验证此路点的可用性,需要考虑的是当前路点是否超出棋盘范围和此路点是否已经走过。

如果新路点可用,则入栈,并执行下一步,重复进行如上步骤,每次按照已走路点的位置生成新路点。

如果一个路点的可扩展路数为0,进行回溯,直到找到一个马能踏遍棋盘的行走路线并输出。

四. 需求分析1. 让用户输入马的初始位置;2. 按照马的行走路线,判断马是否能够走遍整个棋盘;3. 输出结果(若能走遍,则输出马的行走路线,若不能,提示用户“此时不能踏遍棋盘上所有点!”)五. 概要设计为了实现上述程序功能,程序包含以下几大模块:第一步:定义四个常量和一个数据类型:MAXNUM、INVALIDDIR、MAXLEN、MAXDIR、HorsePoint 第二步:构造函数:void Initial() //初始化函数;void PushStack(HorsePoint positon) //入栈函数;HorsePoint GetInitPoint() //请求用户输入函数;HorsePoint GetNewPoint(HorsePoint *parent) //产生新节点函数;void CalcPoint(HorsePoint hh) //计算路径的函数;void PrintChess() //输出函数;int main(int argc,char* argv[]) //主函数六. 详细设计(给出算法的伪码描述和流程图)总体操作步骤如下:流程图设计:代码分析:第一步:定义常量与变量:常量:MAXNUM 8 ---------- /*横纵格数的最大值*/INVALIDDIR -1 ---------- /*无路可走的情况*/MAXLEN 64 ---------- /*棋盘总个数*/MAXDIR 8 ---------- /*下一步可走的方向*/ 变量:HorsePoint ChessPath[MAXLEN] /*模拟路径栈*/Int count /*入栈节点个数*/int ChessBoard[MAXNUM][MAXNUM] /*标志棋盘数组*/ 第二步:构造函数:为了明确马将要走的路线,我们必须定义一个结构体类型:typedef struct{int x; /*表示横坐标*/int y; /*表示纵坐标*/int direction; /*表示移动方向*/ }HorsePoint;●创建一个初始化函数:void Initial() /{int i,j;for(i=0;i<MAXNUM;i++)for(j=0;j<MAXNUM;j++)ChessBoard[i][j]=0; /*棋盘格均初始化为0,代表没走过*/for(i=0;i<MAXLEN;i++){ChessPath[i].x=0;ChessPath[i].y=0;ChessPath[i].direction=INVALIDDIR;}count=0; /*栈中最初没有元素*/}●创建提示输入函数HorsePoint GetInitPoint(){HorsePoint positon;do{printf("\n请输入起始点(y,x):");scanf("%d,%d",&positon.x,&positon.y);printf("\n请稍等......\n");printf("\n\n");}while(positon.x>=MAXNUM || positon.y>=MAXNUM || positon.x<0 || positon.y<0); /*不超过各个边缘时*/positon.direction=INVALIDDIR; /*是初值,没走过*/return positon;}创建产生新节点函数:HorsePoint GetNewPoint(HorsePoint *parent){int i;HorsePoint newpoint;/*能走的8个方向的坐标增量*/int tryx[MAXDIR]={ 1, 2, 2, 1,-1,-2,-2,-1};int tryy[MAXDIR]={-2,-1, 1, 2, 2, 1,-1,-2};/*新结点可走方向初始化*/newpoint.direction=INVALIDDIR;parent->direction=parent->direction++; /*上一结点能走的方向*/for(i=parent->direction;i<MAXDIR;i++){newpoint.x=parent->x+tryx[i]; /*试探新结点的可走方向*/newpoint.y=parent->y+tryy[i];if(newpoint.x<MAXNUM&&newpoint.x>=0&&newpoint.y<MAXNUM&&newpoint.y>=0 &&ChessBoard[newpoint.x][newpoint.y]==0){parent->direction=i; /*上一结点可走的方向*/ChessBoard[newpoint.x][newpoint.y]=1; /*标记已走过*/return newpoint;}}parent->direction=INVALIDDIR;return newpoint;}创建计算路径函数:void CalcPoint(HorsePoint hh){HorsePoint npositon;HorsePoint *ppositon;Initial(); /*调用初始化函数*/ppositon=&hh; /*调用输入起始点函数*/PushStack(*ppositon);while(!(count==0 || count==MAXLEN))/*当路径栈不空或不满时*/{ppositon=&ChessPath[count-1]; /*指针指向栈*/npositon=GetNewPoint(ppositon); /*产生新结点*/if(ppositon->direction!=INVALIDDIR) /*如果可以往下走*/{ChessPath[count-1].direction=ppositon->direction;PushStack(npositon);}elsePopStack();}}●创建入栈函数:void PushStack(HorsePoint positon) /*入栈函数*/{ChessBoard[positon.x][positon.y]=1; /*把标志设为1,证明已走过*/ChessPath[count]=positon; /*把标志为1的结点入栈*/count++; /*栈中结点个数加1*/}●创建出栈函数:HorsePoint PopStack() /*出栈函数*/{HorsePoint positon;count--;positon=ChessPath[count];ChessBoard[positon.x][positon.y]=0;ChessPath[count].direction=INVALIDDIR;return positon;}●创建输出函数:void PrintChess() /*以8*8矩阵的形式输出运行结果*/{int i,j;/*state[i][j]为棋盘上(i,j)点被踏过的次序*/int state[MAXNUM][MAXNUM];int step=0; /*行走步数初始化*/HorsePoint positon;count=MAXLEN;if(count==MAXLEN) /*当棋盘全部走过时*/{for( i=0;i<MAXLEN;i++){step++;positon=ChessPath[i];state[positon.x][positon.y]=step;}for(i=0;i<MAXNUM;i++){printf("\t\t");for( j=0;j<MAXNUM;j++){if(state[i][j]<10)printf(" ");printf("%d ",state[i][j]); /*按顺序输出马踏过的点*/}printf("\n");}printf("\n");}elseprintf("\t\t此时不能踏遍棋盘上所有点!\n");}第三步:在主函数中调用其它函数int main(int argc,char* argv[]){HorsePoint h; /*定义一个结构体类型的变量*/h=GetInitPoint(); /*将用户输入的数据赋给变量h*//*先调用初始化函数,然后将用户输入的数据入栈,判断马的行走方向,确定后,产生新节点,将新节点入栈,直到马踏遍整个棋盘或者无法踏遍整个棋盘为止。

相关文档
最新文档