马踏棋盘-大学课程设计
- 格式:doc
- 大小:169.00 KB
- 文档页数:10
马踏棋盘c语言课程设计一、教学目标本课程的目标是让学生掌握C语言的基本语法、数据结构、算法和编程技巧,培养学生独立思考、解决问题和合作交流的能力。
具体分为以下三个部分:1.知识目标:学生能够理解并掌握C语言的基本语法、数据类型、运算符、控制结构、函数、数组、指针等概念,了解C语言的面向对象编程思想。
2.技能目标:学生能够运用C语言编写简单的程序,解决实际问题,具备一定的编程能力。
3.情感态度价值观目标:培养学生对计算机科学的兴趣,增强自信心,培养克服困难的勇气和团队协作精神。
二、教学内容教学内容主要包括C语言的基本语法、数据结构、算法和编程技巧。
具体安排如下:1.第一章:C语言概述,介绍C语言的发展历程、特点和基本语法。
2.第二章:数据类型和运算符,讲解整型、浮点型、字符型数据以及各类运算符的用法。
3.第三章:控制结构,包括条件语句、循环语句和跳转语句。
4.第四章:函数,讲解函数的定义、声明、调用以及函数的参数传递。
5.第五章:数组和指针,介绍数组的声明、初始化和使用,以及指针的基本概念和应用。
6.第六章:字符串和文件操作,讲解字符串的表示、操作方法以及文件读写。
7.第七章:编程实践,通过实际项目让学生综合运用所学知识解决实际问题。
三、教学方法本课程采用多种教学方法,包括讲授法、案例分析法、实验法和讨论法。
1.讲授法:用于讲解C语言的基本语法、数据结构和算法。
2.案例分析法:通过分析实际项目,让学生了解C语言在实际中的应用。
3.实验法:让学生动手编写程序,培养实际编程能力。
4.讨论法:鼓励学生提问、交流和分享,培养合作交流能力。
四、教学资源1.教材:《C程序设计语言》(K&R)或《C Primer Plus》。
2.参考书:《C语言编程之美》、《C语言深度剖析》。
3.多媒体资料:PPT课件、教学视频、在线教程。
4.实验设备:计算机、编程环境(如Code::Blocks、Visual Studio等)。
《数据结构》课程设计报告课程名称:《数据结构》课程设计课程设计题目:姓名:院系:专业:年级:学号:指导教师:2011年月日目录1、程序设计的目的2、设计题目3、分析4、设计思想5、算法6、测试结果7、调试分析8、小结1、课程设计的目的1、熟练使用C++语言编写程序,解决实际问题;2、了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;3、初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;4、提高综合运用所学的理论知识和方法独立分析和解决问题的能力;5、学习并熟悉栈的有关操作;6、利用栈实现实际问题;2、设计题目【马踏棋盘】*问题描述:将马随机放在国际象棋的8X8棋盘Bo阿rd[0..7,0..7]的某个方格中,马按走棋规则进行移动。
要求每个方格上只进入一次,走遍棋盘上全部64个方格。
编制非递归程序,求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入8X8的方阵输出之。
*测试数据:由读者指定,可自行指定一个马的初始位置。
*实现提示:每次在多个可走位置中选择一个进行试探,其余未曾试探过的可走位置必须用适当结构妥善管理,以备试探失败时的“回溯”(悔棋)使用。
并探讨每次选择位置的“最佳策略”,以减少回溯的次数。
3、分析确定输入值的范围,输入马的初始行坐标X和Y,X和Y的范围都是1到8之间。
程序的功能是输出马走的步骤,要使马从任一起点出发,通过程序能找到下一个地点,然后遍历整个棋盘。
每次在多个可走位置中选择一个进行试探,其余未曾试探过的可走位置必须用适当结构妥善管理,以备试探失败时的“回溯”(悔棋)使用。
并探讨每次选择位置的“最佳策略”,以减少回溯的次数。
输出时可以用二维数组。
4、设计思想输入马初始位置的坐标。
将初始位置进栈,经过一个while循环,取出符合条件的栈顶元素。
利用函数,找出栈顶元素周围未被占用的新位置,如果有,新位置入栈;否则弹出栈顶元素。
马踏棋盘课程设计实验报告《数据结构》课程设计实验报告课程名称: 《数据结构》课程设计课程设计题目: 马踏棋盘姓名: 邱可昉院系: 计算机学院专业: 计算机科学与技术班级: 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的方阵输出之。
*测试数据:由读者指定,可自行指定一个马的初始位置。
*实现提示:每次在多个可走位置中选择一个进行试探,其余未曾试探过的可走位置必须用适当结构妥善管理,以备试探失败时的“回溯”(悔棋)使用。
并探讨每次选择位置的“最佳策略”,以减少回溯的次数。
课程设计课程名称:数据结构设计题目: 马踏棋盘的程序设计专业:计算机科学与技术专业班级:0706姓名: 孙禹指导教师: 刘伟2009 年07 月02 日课程设计任务书学生姓名:孙禹专业班级: 07 06 班指导教师:刘伟工作单位:计算机科学系题目: 马踏棋盘的程序设计初始条件:设计一个国际象棋的马踏遍棋盘的演示程序。
将马随机放在国际象棋的8×8棋盘Board[8][8]的某个方格中,马按走棋规则(见题集p98)进行移动。
要求每个方格只进入一次,走边棋盘上全部64个方格。
编制非递归程序,求出马的行走路线,并按求出的行走路线,将数字1,2,3,…,64依次填入一个8×8的方阵,输出之。
测试用例见题集P98。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)课程设计报告按学校规定格式用A4纸打印(书写),并应包含如下内容:1、问题描述简述题目要解决的问题是什么。
2、设计存储结构设计、主要算法设计(用类C语言或用框图描述)、测试用例设计;3、调试报告调试过程中遇到的问题是如何解决的;对设计和编码的讨论和分析。
4、经验和体会(包括对算法改进的设想)5、附源程序清单和运行结果。
源程序要加注释。
如果题目规定了测试数据,则运行结果要包含这些测试数据和运行输出,6、设计报告、程序不得相互抄袭和拷贝;若有雷同,则所有雷同者成绩均为0分。
时间安排:1、第20周(6月29日至7月3日)完成。
2、7月3 日8:00到计算中心检查程序、交课程设计报告、源程序(CD盘)。
指导教师签名:年月日系主任(或责任教师)签名:年月日一、问题描述设计一个国际象棋的马踏棋盘的演示程序。
基本要求:将马随机放在国际象棋8×8的棋盘Board[8][8]的某个方格中,马按走棋规则进行移动。
要求每个方格只进入一次,走遍棋盘全部的64个方格。
编制非递归程序,求出马的行走路线,并按求出的行走路线,将数字1,2,3, …,64一次填入一个8×8的方阵输出之。
马踏棋盘一目的1、巩固和加深对线性表、栈、队列、字符串、树、图、查找、排序等理论知识的理解。
2、掌握现实复杂问题的分析建模和解决方法(包括问题描述、系统分析、设计建模、代码实现、结果分析等)。
3、提高利用计算机分析解决综合性实际问题的基本能力。
4、加强对基础知识的运用,做到学以致用。
5、二需求分析1、从键盘输入马起始的横坐标x和纵坐标y,其范围都是0-7。
2、马按走棋规则进行移动,要求每个方格只进入一次,走遍棋盘上全部64个方格。
3、一般说来,当马位于位置(i,j)时,可以走到下列8个位置之一( x-2,y+1),(x-1,y+2),(x+1,y+2),(x+2,y+1),(x+2,y-1)(x+1,y-2),(x-1,y-2),(x-2,y-1)4、求出马的行走路线,将数字1到64依次填入一个8X8的方阵,输出到文本中(文本中能清楚看到方阵)。
输出的形式;(1)以数组下标形式输入,代表起始位置,i表示行标,j表示列标。
(2)以棋盘形式输出,每一格打印马走的步数,这种方式比较直观。
3、程序所能达到的功能;(1)让马从任一起点出发都能够历遍整个8×8的棋盘。
(2)能寻找多条不同的行走路径。
4.测试数据,包括正确的输入及输出结果和含有错误的输入及其输出结果。
数据可以任定,只要 0<=X<7&&0<=Y<7 就可以了。
正确的输出结果为一个2维数组,每个元素的值表示马行走的第几步。
若输入有错,程序会显示“输入错误,请重新输入:”并且要求用户重新输入数据,直至输入正确为止。
三概要设计initstack(s) //构建一个空栈。
push(s,e) //在栈顶插入新的元素。
pop(s,e)//将栈顶元素弹出。
settop(s, e) //将e设为栈顶元素。
gettop(s, e)//将栈顶元素取出。
stackempty(s) //判断栈是否为空check(int x,int y)//判断点(x,y)是否在棋盘内weighting()//求棋盘中每一点的权值四详细设计1、名称详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详棋盘点的结构类型定义typedef struct{int x;该点的横坐标int y;该点的纵坐标int z;}elemtype;栈的类型定义typedef struct SNode{elemtype data;struct SNode *next;}SNode,*Linkstack;栈的初始化操作int initstack(Linkstack &s){s=(Linkstack)malloc(sizeof(SNode));if(!s){printf("初始化失败!");return 0;}s->next=NULL;return 1;}入栈操作int push(Linkstack &s,elemtype e){Linkstack p;p=(Linkstack)malloc(sizeof(SNode));if(!p) return 0;p->next=s->next;s->next=p;p->data=e;return 1;}出栈操作int pop(Linkstack &s,elemtype &e) {Linkstack p=s->next;if(p==NULL) return 0;s->next=p->next;e=p->data;free(p);return 1;}取栈顶元素操作gettop(Linkstack &s,elemtype &e) {Linkstack p=s->next;if(p==NULL) return 0;e=p->data;return 1;}判断栈是否为空操作int stackempty(Linkstack s){int flag=0;if(s->next==NULL)flag=1;return flag;}设为栈顶元素操作int settop(Linkstack &s,elemtype e) {if(s->next!=NULL){s->next->data=e;return 1;}else return 0;}void setmap(){int i,j,k,m,d1,d2,x1,x2,y1,y2,l1,l2; for(i=0;i<N;i++)//for 1{for(j=0;j<N;j++)//for 2{for(k=0;k<8;k++)map[i][j][k]=k;//默认8个方向顺时针赋值for(k=0;k<8;k++)//for 3 与 for 4 两个循环对方向索引按点的权值升序排列,不能到达的方向排在最后{for(m=k+1;m<8;m++) //for 4{d1=map[i][j][k];x1=i+HTry1[d1];y1=j+HTry2[d1];d2=map[i][j][m];x2=i+HTry1[d2];y2=j+HTry2[d2];l1=check(x1,y1);l2=check(x2,y2);if((l1==0&&l2)||(l1&&l2&&(weight[x1][y1]>weight[x2][y2]))){map[i][j][k]=d2;map[i][j][m]=d1; //交换两个方向值,按权值递增排列,不可到达的目标点(超出棋盘)的方向放在最后面}//end if}//end for 4}//end for 3}//end for 2}//end for 1}//end setmap()void path(int xx, int yy){ int c[N*N]={0},h[N*N]={0};Linkstack a;elemtype ptemp;elemtype pop_temp,get_temp;elemtype p,dest_p; //当前点和目标点int step=0,x,y,s,k=1,l=1,d =0;char ch;p.x = xx; p.y = yy;p.z = 0;//初始化出发点board[xx][yy]=1;initstack(a);push(a,p); //起始点的坐标和首选方向入栈while(1){if (step==63){output(a);exit(1);}if(stackempty(a)) break;gettop(a,p);x=p.x; y=p.y; d=p.z;if(d>=8)//该点所有方向已走完,退栈{board[x][y]=0; //抹去痕迹step--; //步数减一pop(a,pop_temp); //退栈gettop(a,get_temp); //取当前栈顶元素ptemp.x=get_temp.x;ptemp.y=get_temp.y;ptemp.z=get_temp.z+1;settop(a,ptemp); //更改方向gettop(a,p);} //end if (d>=8)if(d<8)//方向未走完{s=map[x][y][d];//map[x][y][0]未必是(x,y)点的HTry[0]方向,而是到该点可到的权值最小的点的方向即HTry[map[x][y][0]dest_p.x=x+HTry1[s];dest_p.y=y+HTry2[s];if(check(dest_p.x,dest_p.y)&&board[dest_p.x][dest_p.y]==0)//目标点在棋盘内且未被走过,则将目标点入栈同时标记当前点为已走过{h[step]=step;board[x][y]=1;step++;//步数加一dest_p.z=0;push(a,dest_p);//存入目标点,方向栈初始}else//目标点已被走过或目标点不在棋盘内,换方向{ //printf(" 进行");ptemp.x=p.x;ptemp.y=p.y;ptemp.z=d+1;//取下一个方向 settop(a,ptemp);//切换方向// gettop(a,p);//gettop(a,p);//x=p.x; y=p.y; d=p.z;检测重新将d赋值//printf("%d %d %d",x,y,d);}} //enf if(d<8)//printf("步数%d\n ",step);} //end while(1)}void output(Linkstack a){ Linkstack b;int c[8][8]={0},i,j,k=N*N,l=1,x,y;initstack(b);elemtype e;while(!stackempty(a)){pop(a,e);c[e.x][e.y]=k;k--;push(b,e);}gettop(b,e);x=e.x;y=e.y;printf("起始坐标:(%d,%d)\n",x,y);while(!stackempty(b)){ pop(b,e);printf("(%d,%d)",e.x,e.y);push(a,e);}printf("棋盘表示为:\n");for(i=0;i<8;i++){for(j=0;j<8;j++){printf("%2d",c[i][j]);printf(" ");if(j==7) printf("\n");}}}五调试分析1、设计gettop函数时误将栈顶元素取出,原因是多加了一条s->next=p->next语句,造成不应有的错误2、写settop(s)函数时,忘记了s仅为头结点误将e赋值给了s->data,而实际上应为s->next->data=e;由此造成的错误极难发现,这也进一步说明了基础知识的重要。
一、问题描述问题描述:将马随机放在国际象棋的8X8棋盘Bo阿rd[0..7,0..7]的某个方格中,马按走棋规则进行移动。
要求每个方格上只进入一次,走遍棋盘上全部64个方格。
编制非递归程序,求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入8X8的方阵输出之。
测试数据:由读者指定,可自行指定一个马的初始位置。
实现提示:每次在多个可走位置中选择一个进行试探,其余未曾试探过的可走位置必须用适当结构妥善管理,以备试探失败时的“回溯”(悔棋)使用。
并探讨每次选择位置的“最佳策略”,以减少回溯的次数。
二、实验目的熟练使用栈和队列解决实际问题;(1)了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;(2)初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;(3)提高综合运用所学的理论知识和方法独立分析和解决问题的能力;三、设计过程算法设计思想:根据分析先建了2个结构体struct PosType //马的坐标位置类型{int m_row; //行值int m_col; //列值};struct DataType //栈的元素类型8 17 26 35 4{PosType seat; //马在棋盘中的“坐标位置”int di; //换方向的次数};chess::chess()bool chess::chessPath(PosType start) //在棋盘中进行试探寻找下一步位置并同时记录位置,以及涉及到的入栈出栈void chess::Print() //打印马走的路径PosType chess::NextPos(PosType a,int di)//根据当前点的位置a和移动方向di,试探下一位置(1)、位置的存储表示方式typedef struct{int x;int y;int from;}Point;(2)、栈的存储方式#define STACKSIZE 70#define STACKINCREASE 10typedef struct Stack{Point *top;Point *base;int stacksize;};(3)设定栈的抽象数据类型定义:ADT Stack {数据对象:D={a i | a i∈ElemSet,i=1,2,…,n,n≥0}数据关系:R1={<a i-1 , a i>|a i-1, a i∈D,i=2,…,n}约定a n端为栈顶,a i端为栈顶。
数据结构课程设计报告设计题目:马踏棋盘院系计算机学院年级 11 级学生xxxxxxx学号xxxxxxxxx指导教师 xxxxxxxxx起止时间 9-6/9-132018年9月10日星期二目录一、课程设计目的------------------------------------------------------3二、需求分析-------------------------------------------------------------3三、程序源代码------------------------------------------------------------ 4四、调试分析----------------------------------------------------------------7五、问题总结----------------------------------------------------------------8六、参考资料-----------------------------------------------------------------9一、课程设计目的(1> 熟练使用 C 语言编写程序,解决实际问题。
(2> 了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力。
(3> 初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能。
(4> 提高综合运用所学的理论知识和方法独立分析和解决问题的能力。
二、需求分析问题描述:将马随机放在国际象棋的 8X8 棋盘中的某个方格中,马按走棋规则进行移动。
要求每个方格上只进入一次,走遍棋盘上全部 64 个方格。
编制递归程序,求出马的行走路线,并按求出的行走路线,将数字 1,2,…,64 依次填入 8X8 的方阵输出之。
测试数据:由读者指定可自行指定一个马的初始位置。
杭州师范大学钱江学院课程设计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。
数据结构课程设计实习报告题目:马踏棋盘(实习题 2.4 )班级:计算机科学与技术2004 班学031010151552010号:姓游尾妹名:日期:二OO五年七月八日指导老师:李杨老师源程序结构1. 定义函数caculate () 计算各点的权值dirctions () 求出各点的最佳方向序列,即优先向权值小的方向,以使运行速度加快 check (int i,int j ) 检查( i,j )是否在棋盘内print () 输出路径走过的序号2. 程序步骤简介(1) 计算各点的权值,方向(2) 用户输入行数和列数(3) 寻找点的八个可走方向,若所有方向都已走过,则退回前一步,并将此步 抹去,使前一步的方向发生变化。
( 4) 确定下一步该走的方向,依次走完全部点(5) 记录每一步(6) 当步数已满时输出,根据需要可输出一条或多条路径3. 源程序描述#include "stdio.h" #define N 8int w=0; /* 第几条可走路径 */int way1[8]={-2,-1,1,2, 2, 1,-1,-2};int way2[8]={ 1,2, 2,1,-1,-2,-2,-1}; /*在( i,j )位置处的 8 个可能走的位置 */ int ch[N*N]={0}; /*走过的相应的点的赋值 */int a[N*N+1][3]={0}; /* 路径所经过点的记录 */int dir[N][N][8];/* ( i,j )点的八个可能走的方向 */ int st=1; /* 走过的步数 *//* 每个点的权值 *//* 计算各点的权值 */ 求出各点的最佳方向序列,即优先向权值小的方向 /* 输出路径走过的序号 */ /* /*检查(i,j )是否在棋盘内*/ 计算各点的权值,将权值存在 weight[i][j] 中*//*int i,j,k;for(i=1;i<=N;i++)for(j=1;j<=N;j++) for(k=0;k<N;k++)char c='y'; int weight[N][N]; void caculate(); voiddirctions(); voidprint(); intcheck(int i,int j);void caculate() { */int x,y;x=i+way1[k];y=j+way2[k]; /* 下一步走的点 */if(x>=1&&x<=N&&y>=1&&y<=N)weight[i-1][j-1]++; /*权值 */ }}int check(int i,int j) /*检查 (i,j) 是否在棋盘内,在返回 1,不在返回 {if(i<1||i>8||j<1||j>8)return 0;return 1;}void directions() /* 求出各点的最佳方向序列,即优先向权值小的方向 {int i,j,k,m,n1,n2,x1,y1,x2,y2,way_1,way_2; for(i=0;i<N;i++)0*/ */ for(j=0;j<N;j++){ for(k=0;k<8;k++)dir[i][j][k]=k; for(k=0;k<8;k++) for(m=k+1;m<8;m++) { way_1=dir[i][j][k]; x1=i+way1[way_1];y1=j+way2[way_1];way_2=dir[i][j][m]; x2=i+way1[way_2];y2=j+way2[way_2];n1=check(x1+1,y1+1); n2=check(x2+1,y2+1);{/* 对每个方向考察看有没有更好的*//*k 方向时的下一个点 *//*m 方向时的下一个点 *//*判断 n1,n2 是否在棋盘内*/if(( n1==0 && n2)||( n1 && n2&&weight[x1][y1]>weight[x2][y2])) 到,而 m 方向可达到 */ || /*都可达到,但 m 方向权值小 *//*k 方向不可达 { dir[i][j][k]=way_2;dir[i][j][m]=w ay_1; 即权值小的一步) *//* 交换两个方向值,将 k 走更好的一步棋 }}void print() /* 输出路径走过的序号 */ {int x,y;printf("\n - %d answer --- \n",++w); for(x=1;x<N+1;x++) /*输出是第 w 条路径的序号 */printf("\n");printf("\n");}printf("\nPress n to quit ,press any other key to continue.\n"); c=getchar(); /* 询问是否继 续输出结果 */}main(){int x,y,way,way0; caculate();directions();printf("Please enter the row and column of the starting point.\n");scanf("%d,%d",&a[1][0],&a[1][1]); /* 输入行数和列数 */getchar();y=a[st][1];ch[(x-1)*N+y-1]=0; /* 将这一点被走过的痕迹抹去 */a[st][0]=a[st][1]=a[st][2]=0;a[st-1][2]++; /* 将上一次走的点走的方向发生变化 */st--; /* 步数减一 */}else /* 此点的八个方向未全走过,应走此方向 */{way0=a[st][2];a[st][2]++; /* 确定下次应走的方向 */ x=a[st][0];y=a[st][1]; way=dir[x-1][y-1][way0];x=a[st][0]+way1[way];y=a[st][1]+way2[way]; /* 确定按这次的方向走应走到的 x,y 坐标 */ if(x<1||y<1||x>N||y>N||ch[(x-1)*N+y-1]!=0)continue; /* 此点不满足要求 */ a[st][0]=x; a[st][1]=y;a[st][2]=0; if(st==N*N){ p rint(); /* 标记这一点*//* 步数已满 *//* 输出结果 */if(c=='n')break; a[st][0]=a[st][1]=a[st][2]=0;a[st-1][2]++;}}}}二、 程序运行结果 for(y=1;y<N+1;y++)printf("%2d ",ch[(x-1)*N+y-1]); x=a[1][0],y=a[1][1];ch[(x-1)*N+y-1]=1; while(1){if(a[1][2]>=8)break; if(a[st][2]>=8) { x=a[st][0]; /*在 ch 数组中对相应点赋值,即输出时用到的各点的顺序号/* 出发点的八个方向都已走过,表示所有的方法均已找出 此点的八个方向都已走过,应该退回到上一次走的点 */ */ */ ch[(x-1)*N+y-1]=++st; /* 走到这一点 */ch[(x-1)*N+y-1]=0;例如:输入数值为2,3 时,并且要求输入第2条路径(只按回车键即可)Please enter the row and column of the starting point.2,3---- 1 answer --2 29 54 15 12 31 56 1753 14 1 30 55 16 11 3228 3 52 13 64 61 18 5751 46 63 60 39 58 33 104 27 50 45 62 37 40 1949 24 47 38 59 44 9 3426 5 22 43 36 7 20 4123 48 25 6 21 42 35 8Press n to quit ,press any other key to continue.---- 2 answer --2 29 54 15 12 31 60 1753 14 1 30 55 16 11 3228 3 52 13 64 61 18 5951 46 63 56 39 58 33 104 27 50 45 62 37 40 1949 24 47 38 57 44 9 3426 5 22 43 36 7 20 4123 48 25 6 21 42 35 8Press n to quit ,press any other key to continue.。
马踏棋盘一目的1、巩固和加深对线性表、栈、队列、字符串、树、图、查找、排序等理论知识的理解。
2、掌握现实复杂问题的分析建模和解决方法(包括问题描述、系统分析、设计建模、代码实现、结果分析等)。
3、提高利用计算机分析解决综合性实际问题的基本能力。
4、加强对基础知识的运用,做到学以致用。
5、二需求分析1、从键盘输入马起始的横坐标x和纵坐标y,其范围都是0-7。
2、马按走棋规则进行移动,要求每个方格只进入一次,走遍棋盘上全部64个方格。
3、一般说来,当马位于位置(i,j)时,可以走到下列8个位置之一( x-2,y+1),(x-1,y+2),(x+1,y+2),(x+2,y+1),(x+2,y-1)(x+1,y-2),(x-1,y-2),(x-2,y-1)4、求出马的行走路线,将数字1到64依次填入一个8X8的方阵,输出到文本中(文本中能清楚看到方阵)。
输出的形式;(1)以数组下标形式输入,代表起始位置,i表示行标,j表示列标。
(2)以棋盘形式输出,每一格打印马走的步数,这种方式比较直观。
3、程序所能达到的功能;(1)让马从任一起点出发都能够历遍整个8×8的棋盘。
(2)能寻找多条不同的行走路径。
4.测试数据,包括正确的输入及输出结果和含有错误的输入及其输出结果。
数据可以任定,只要 0<=X<7&&0<=Y<7 就可以了。
正确的输出结果为一个2维数组,每个元素的值表示马行走的第几步。
若输入有错,程序会显示“输入错误,请重新输入:”并且要求用户重新输入数据,直至输入正确为止。
三概要设计initstack(s) //构建一个空栈。
push(s,e) //在栈顶插入新的元素。
pop(s,e)//将栈顶元素弹出。
settop(s, e) //将e设为栈顶元素。
gettop(s, e)//将栈顶元素取出。
stackempty(s) //判断栈是否为空check(int x,int y)//判断点(x,y)是否在棋盘内weighting()//求棋盘中每一点的权值四详细设计1、名称详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详棋盘点的结构类型定义typedef struct{int x;该点的横坐标int y;该点的纵坐标int z;}elemtype;栈的类型定义typedef struct SNode{elemtype data;struct SNode *next;}SNode,*Linkstack;栈的初始化操作int initstack(Linkstack &s){s=(Linkstack)malloc(sizeof(SNode));if(!s){printf("初始化失败!");return 0;}s->next=NULL;return 1;}入栈操作int push(Linkstack &s,elemtype e){Linkstack p;p=(Linkstack)malloc(sizeof(SNode));if(!p) return 0;p->next=s->next;s->next=p;p->data=e;return 1;}出栈操作int pop(Linkstack &s,elemtype &e) {Linkstack p=s->next;if(p==NULL) return 0;s->next=p->next;e=p->data;free(p);return 1;}取栈顶元素操作gettop(Linkstack &s,elemtype &e) {Linkstack p=s->next;if(p==NULL) return 0;e=p->data;return 1;}判断栈是否为空操作int stackempty(Linkstack s){int flag=0;if(s->next==NULL)flag=1;return flag;}设为栈顶元素操作int settop(Linkstack &s,elemtype e) {if(s->next!=NULL){s->next->data=e;return 1;}else return 0;}void setmap(){int i,j,k,m,d1,d2,x1,x2,y1,y2,l1,l2; for(i=0;i<N;i++)//for 1{for(j=0;j<N;j++)//for 2{for(k=0;k<8;k++)map[i][j][k]=k;//默认8个方向顺时针赋值for(k=0;k<8;k++)//for 3 与 for 4 两个循环对方向索引按点的权值升序排列,不能到达的方向排在最后{for(m=k+1;m<8;m++) //for 4{d1=map[i][j][k];x1=i+HTry1[d1];y1=j+HTry2[d1];d2=map[i][j][m];x2=i+HTry1[d2];y2=j+HTry2[d2];l1=check(x1,y1);l2=check(x2,y2);if((l1==0&&l2)||(l1&&l2&&(weight[x1][y1]>weight[x2][y2]))){map[i][j][k]=d2;map[i][j][m]=d1; //交换两个方向值,按权值递增排列,不可到达的目标点(超出棋盘)的方向放在最后面}//end if}//end for 4}//end for 3}//end for 2}//end for 1}//end setmap()void path(int xx, int yy){ int c[N*N]={0},h[N*N]={0};Linkstack a;elemtype ptemp;elemtype pop_temp,get_temp;elemtype p,dest_p; //当前点和目标点int step=0,x,y,s,k=1,l=1,d =0;char ch;p.x = xx; p.y = yy;p.z = 0;//初始化出发点board[xx][yy]=1;initstack(a);push(a,p); //起始点的坐标和首选方向入栈while(1){if (step==63){output(a);exit(1);}if(stackempty(a)) break;gettop(a,p);x=p.x; y=p.y; d=p.z;if(d>=8)//该点所有方向已走完,退栈{board[x][y]=0; //抹去痕迹step--; //步数减一pop(a,pop_temp); //退栈gettop(a,get_temp); //取当前栈顶元素ptemp.x=get_temp.x;ptemp.y=get_temp.y;ptemp.z=get_temp.z+1;settop(a,ptemp); //更改方向gettop(a,p);} //end if (d>=8)if(d<8)//方向未走完{s=map[x][y][d];//map[x][y][0]未必是(x,y)点的HTry[0]方向,而是到该点可到的权值最小的点的方向即HTry[map[x][y][0]dest_p.x=x+HTry1[s];dest_p.y=y+HTry2[s];if(check(dest_p.x,dest_p.y)&&board[dest_p.x][dest_p.y]==0)//目标点在棋盘内且未被走过,则将目标点入栈同时标记当前点为已走过{h[step]=step;board[x][y]=1;step++;//步数加一dest_p.z=0;push(a,dest_p);//存入目标点,方向栈初始}else//目标点已被走过或目标点不在棋盘内,换方向{ //printf(" 进行");ptemp.x=p.x;ptemp.y=p.y;ptemp.z=d+1;//取下一个方向 settop(a,ptemp);//切换方向// gettop(a,p);//gettop(a,p);//x=p.x; y=p.y; d=p.z;检测重新将d赋值//printf("%d %d %d",x,y,d);}} //enf if(d<8)//printf("步数%d\n ",step);} //end while(1)}void output(Linkstack a){ Linkstack b;int c[8][8]={0},i,j,k=N*N,l=1,x,y;initstack(b);elemtype e;while(!stackempty(a)){pop(a,e);c[e.x][e.y]=k;k--;push(b,e);}gettop(b,e);x=e.x;y=e.y;printf("起始坐标:(%d,%d)\n",x,y);while(!stackempty(b)){ pop(b,e);printf("(%d,%d)",e.x,e.y);push(a,e);}printf("棋盘表示为:\n");for(i=0;i<8;i++){for(j=0;j<8;j++){printf("%2d",c[i][j]);printf(" ");if(j==7) printf("\n");}}}五调试分析1、设计gettop函数时误将栈顶元素取出,原因是多加了一条s->next=p->next语句,造成不应有的错误2、写settop(s)函数时,忘记了s仅为头结点误将e赋值给了s->data,而实际上应为s->next->data=e;由此造成的错误极难发现,这也进一步说明了基础知识的重要。
3、当函数执行中出现错误设置变量进行输出检验时,由于误用了函数中已用的变量名,结果导致了更多错误的出现,且无从查起。
4、因为在子函数中使用了exit()语句导致当程序执行到该语句是直接退出程序而没有继续执行其所在函数后面的语句,造成错误。
六测试结果1、名称正确输入马的坐标的情况:输入坐标有误的情况:继续进行操作的情况:(1:继续 0:退出)详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容详细内容……。