农夫过河和骑士周游(数据结构课程设计)教学内容
数据结构实验-农夫过河问题
农夫过河问题一、实验目的掌握广度优先搜索策略,并用队列求解农夫过河问题二、实验内容问题描述:一农夫带着一只狼,一只羊和一颗白菜,身处河的南岸,他要把这些东西全部运到北岸,遗憾的是他只有一只小船,小船只能容下他和一件物品。
这里只能是农夫来撑船,同时因为狼吃羊、羊吃白菜、所以农夫不能留下羊和狼或羊和白菜在河的一边,而自己离开;好在狼属肉食动物,不吃白菜。
农夫怎么才能把所有的东西安全运过河呢?实验要求如下:(1)设计物品位置的表示方法和安全判断算法;(2)设计队列的存储结构并实现队列的基本操作(建立空队列、判空、入队、出队、取对头元素),也可以使用STL中的队列进行代码的编写;(3)采用广度优先策略设计可行的过河算法;(4)输出要求:按照顺序输出一种可行的过河方案;提示:可以使用STL中的队列进行代码编写。
程序运行结果:二进制表示:1111011011100010101100011001,0000三、农夫过河算法流程⏹Step1:初始状态0000入队⏹Step2:当队列不空且没有到达结束状态1111时,循环以下操作:⏹队头状态出队⏹按照农夫一个人走、农夫分别带上三个物品走,循环以下操作:⏹农夫和物品如果在同一岸,则计算新的状态⏹如果新状态是安全的并且是没有处理过的,则更新path[ ],并将新状态入队⏹当状态为1111时,逆向输出path[ ]数组附录一:STL中队列的使用注:队列,可直接用标准模板库(STL)中的队列。
需要#include<queue>STL中的queue,里面的一些成员函数如下(具体可以查找msdn,搜索queue class):front:Returns a reference to the first element at the front of the queue.pop:Removes an element from the front of the queuepush:Adds an element to the back of the queueempty:Tests if the queue is empty三、实验代码FarmerRiver.H#ifndef FARMERRIVER_H#define FARMERRIVER_Hint FarmerOnRight(int status); //农夫,在北岸返回1,否则返回0int WorfOnRight(int status); //狼int CabbageOnRight(int status); //白菜int GoatOnRight(int status); //羊int IsSafe(int status); //判断状态是否安全,安全返回1,否则返回0void FarmerRiver();#endifSeqQueue.h#ifndef SEQQUEUE_H#define SEQQUEUE_Htypedef int DataType;struct Queue{int Max;int f;int r;DataType *elem;};typedef struct Queue *SeqQueue;SeqQueue SetNullQueue_seq(int m);int IsNullQueue_seq(SeqQueue squeue);void EnQueue_seq(SeqQueue squeue, DataType x);void DeQueue_seq(SeqQueue);DataType FrontQueue_seq(SeqQueue);#endifFarmerRiver.c#include <stdio.h>#include <stdlib.h>#include "SeqQueue.h"#include "FarmerRiver.h"int FarmerOnRight(int status) //判断当前状态下农夫是否在北岸{return (0!=(status & 0x08));}int WorfOnRight(int status){return (0!=(status & 0x04));}int CabbageOnRight(int status){return (0!=(status & 0x02));}int GoatOnRight(int status){return (0!=(status & 0x01));}int IsSafe(int status) //判断当前状态是否安全{if ((GoatOnRight(status)==CabbageOnRight(status)) &&(GoatOnRight(status)!=FarmerOnRight(status)))return (0); //羊吃白菜if ((GoatOnRight(status)==WorfOnRight(status)) && (GoatOnRight(status)!=FarmerOnRight(status))) return 0; //狼吃羊return 1; //其他状态是安全的}void FarmerRiver(){int i, movers, nowstatus, newstatus;int status[16]; //用于记录已考虑的状态路径SeqQueue moveTo;moveTo = SetNullQueue_seq(20); //创建空列队EnQueue_seq(moveTo, 0x00); //初始状态时所有物品在北岸,初始状态入队for (i=0; i<16; i++) //数组status初始化为-1{status[i] = -1;}status[0] = 0;//队列非空且没有到达结束状态while (!IsNullQueue_seq(moveTo) && (status[15]==-1)){nowstatus = FrontQueue_seq(moveTo); //取队头DeQueue_seq(moveTo);for (movers=1; movers<=8; movers<<=1)//考虑各种物品在同一侧if ((0!=(nowstatus & 0x08)) == (0!=(nowstatus & movers)))//农夫与移动的物品在同一侧{newstatus = nowstatus ^ (0x08 | movers); //计算新状态//如果新状态是安全的且之前没有出现过if (IsSafe(newstatus)&&(status[newstatus] == -1)){status[newstatus] = nowstatus; //记录新状态EnQueue_seq(moveTo, newstatus); //新状态入队}}}//输出经过的状态路径if (status[15]!=-1){printf("The reverse path is: \n");for (nowstatus=15; nowstatus>=0; nowstatus=status[nowstatus]){printf("The nowstatus is: %d\n", nowstatus);if (nowstatus == 0)return;}}elseprintf("No solution.\n");}Sequeue.c#include <stdio.h>#include <stdlib.h>#include "SeqQueue.h"SeqQueue SetNullQueue_seq(int m){SeqQueue squeue;squeue = (SeqQueue)malloc(sizeof(struct Queue));if (squeue==NULL){printf("Alloc failure\n");return NULL;}squeue->elem = (int *)malloc(sizeof(DataType) * m);if (squeue->elem!=NULL){squeue->Max = m;squeue->f = 0;squeue->r = 0;return squeue;}else free(squeue);}int IsNullQueue_seq(SeqQueue squeue){return (squeue->f==squeue->r);}void EnQueue_seq(SeqQueue squeue, DataType x) //入队{if ((squeue->r+1) % squeue->Max==squeue->f) //是否满printf("It is FULL Queue!");else{squeue->elem[squeue->r] = x;squeue->r = (squeue->r+1) % (squeue->Max);}}void DeQueue_seq(SeqQueue squeue) //出队{if (IsNullQueue_seq(squeue))printf("It is empty queue!\n");elsesqueue->f = (squeue->f+1) % (squeue->Max); }DataType FrontQueue_seq(SeqQueue squeue) //求队列元素{if (squeue->f==squeue->r)printf("It is empty queue!\n");elsereturn (squeue->elem[squeue->f]);}main.c#include <stdio.h>#include <stdlib.h>#include "FarmerRiver.h"int main(void){FarmerRiver();return 0;}实验结果:四、实验总结。
农夫过河问题(数据结构课设)
#include "stdafx.h"#include <stdio.h>/*0代表在河的这边;1代表在河的对岸*/struct Condition {int farmer;int wolf;int sheep;int cabbage;};/*设置结构体*/struct Condition conditions [100];/*结构体条件数组*/char* action[100];/*字符串数组*/ void takeWolfOver(int i)/*把狼带过去*/ {action[i] = "带狼过去. (wolf)--->对岸";conditions[i+1].wolf=1;conditions[i+1].sheep=conditions[i].sheep;conditions[i+1].cabbage=conditions[i].cabbage;} void takeWolfBack(int i)/*把狼带回来*/{action[i] = "带狼回来. 本岸<---(wolf)";conditions[i+1].wolf=0;conditions[i+1].sheep=conditions[i].sheep;conditions[i+1].cabbage=conditions[i].cabbage;} void takeSheepOver(int i)/*把羊带过去*/{action[i] = "带羊过去. (sheep)--->对岸";conditions[i+1].wolf=conditions[i].wolf;conditions[i+1].sheep=1;conditions[i+1].cabbage=conditions[i].cabbage;} void takeSheepBack(int i)/*把羊带回来*/{action[i] = "带羊回来. 本岸<---(sheep)";conditions[i+1].wolf=conditions[i].wolf;conditions[i+1].sheep=0;conditions[i+1].cabbage=conditions[i].cabbage;} void takeCabbageOver(int i)/*把菜带过去*/{action[i] = "带菜过去. (cabbage)--->对岸";conditions[i+1].wolf=conditions[i].wolf;conditions[i+1].sheep=conditions[i].sheep;conditions[i+1].cabbage=1;} void takeCabbageBack(int i)/*把菜带回来*/{action[i] = "带菜回来. 本岸<---(cabbage)";conditions[i+1].wolf=conditions[i].wolf;conditions[i+1].sheep=conditions[i].sheep;conditions[i+1].cabbage=0;} void getOverBarely(int i)/*过河时的情况*/{action[i] = "空手过去. (barely)--->对岸";conditions[i+1].wolf=conditions[i].wolf;conditions[i+1].sheep=conditions[i].sheep;conditions[i+1].cabbage=conditions[i].cabbage;/*全不动*/} void getBackBarely(int i)/*返回时的情况*/{action[i] = "空手回来. 本岸<---(barely)";conditions[i+1].wolf=conditions[i].wolf;conditions[i+1].sheep=conditions[i].sheep;conditions[i+1].cabbage=conditions[i].cabbage;} void showSolution(int i)/*显示解决方法*/{int c;printf("\n");printf ("%s\n", "解决办法:");for(c=0; c<i; c++){printf ("step%d: %s\n", c+1, action[c]);/*换行输出*/}printf ("%s\n", "Successful!");}void tryOneStep(int i)/*再试一遍*/{int c;int j;if(i>=100)/*检查循环是否出现问题*/{printf("%s\n", "渡河步骤达到100步,出错!");return;}if(conditions[i].farmer==1&&conditions[i].wolf==1&&conditions[i].sheep==1&&conditions[i].cabbage==1)/*检查是否都过河*/{showSolution(i);/*是的,都过河了.返回*/return;}if((conditions[i].farmer!=conditions[i].wolf &&conditions[i].wolf==conditions[i].sheep)||(conditions[i].farmer!=conditions[i].sheep && conditions[i].sheep==conditions[i].cabbage))/*检查是否丢失,出错*/{/*不,狼会吃掉羊,或者羊会吃掉菜的*/return;}/*检查条件是否满足*/for (c=0; c<i; c++){if(conditions[c].farmer==conditions[i].farmer&&conditions[c].wolf==conditions[i].wolf&&conditions[c].sheep==conditions[i].sheep&&conditions[c].cabbage==conditions[i].cabbage) {return;}}j=i+1;if(conditions[i].farmer==0)/*农夫在河这边*/{conditions[j].farmer=1;getOverBarely(i);tryOneStep(j);if(conditions[i].wolf==0)/*如果狼没带过去*/{takeWolfOver(i);tryOneStep(j);}if(conditions[i].sheep==0){takeSheepOver(i);tryOneStep(j);}if(conditions[i].cabbage==0){takeCabbageOver(i);tryOneStep(j);}}else{conditions[j].farmer=0;getBackBarely(i);tryOneStep(j);if(conditions[i].wolf==1){takeWolfBack(i);tryOneStep(j);}if(conditions[i].sheep==1){takeSheepBack(i);tryOneStep(j);}if(conditions[i].cabbage==1){takeCabbageBack(i);tryOneStep(j);}}} int main()/*主函数*/{printf("问题:农夫过河。
农夫过河问题
课程设计题目:农夫过河一.问题描述一个农夫带着一只狼、一只羊和一箩白菜,身处河的南岸。
他要把这些东西全部运到北岸。
他面前只有一条小船,船只能容下他和一件物品,另外只有农夫才能撑船。
过河有以下规则:(1)农夫一次最多能带一样东西(或者是狼、或者是羊、或者是白菜)过河;(2)当农夫不在场是狼会吃羊;(3)当农夫不在场是羊会吃掉白菜。
现在要求为农夫想一个方案,能将3样东西顺利地带过河。
从出事状态开始,农夫将羊带过河,然后农夫将羊待会来也是符合规则的,然后农夫将羊带过河仍然是符合规则的,但是如此这般往返,搜索过程便进入了死循环,因此,在这里,采用改进的搜索算法进行搜索。
二.基本要求(1)为农夫过河问题抽象数据类型,体会数据模型在问题求解中的重要性;(2)要求利用数据结构的方法以及C++的编程思想来完成问题的综合设计;(3)在问题的设计中,使用深度优先遍历搜索方式,避免死循环状态;(4)设计一个算法求解农夫过河问题,并输出过河方案;(5)分析算法的时间复杂度。
三.概要设计(1)数据结构的设计typedef struct // 图的顶点{int farmer; // 农夫int wolf; // 狼int sheep; // 羊int veget; // 白菜}Vertex;设计Vertex结构体的目的是为了存储农夫、狼、羊、白菜的信息,因为在遍历图的时候,他们的位置信息会发生变化,例如1111说明他们都在河的北岸,而0000说明他们都在河的南岸。
t ypedef struct{int vertexNum; // 图的当前顶点数Vertex vertex[VertexNum]; // 顶点向量(代表顶点)bool Edge[VertexNum][VertexNum]; // 邻接矩阵. 用于存储图中的边,其矩阵元素个数取决于顶点个数,与边数无关}AdjGraph; // 定义图的邻接矩阵存储结构存储图的方法是用邻接矩阵,所以设计一个简单的AdjGraph结构体是为了储图的顶点数与边数,农夫过河问题我采用的是图的深度优先遍历思想。
农夫过河C语言课程设计
农夫过河C语言课程设计一、课程目标知识目标:1. 理解C语言中基本的数据类型和语法结构;2. 学会使用C语言进行逻辑判断和循环控制;3. 掌握C语言中的函数定义和调用方法;4. 了解“农夫过河”问题的背景和解决方案。
技能目标:1. 能够运用C语言编写出解决“农夫过河”问题的程序;2. 培养逻辑思维和问题分析能力,将实际问题转化为程序代码;3. 提高编程实践能力,学会调试和修改代码,解决程序中的错误。
情感态度价值观目标:1. 激发学生对编程的兴趣,培养计算机科学素养;2. 培养学生面对问题积极思考、勇于探索的精神;3. 强调团队合作,学会与他人共同解决问题,培养沟通与协作能力。
分析课程性质、学生特点和教学要求:本课程为C语言编程课程,旨在让学生掌握C语言的基本知识,并通过解决实际问题,提高编程能力。
学生为初中生,具有一定的逻辑思维能力和数学基础。
教学要求注重实践,将理论教学与实际操作相结合,引导学生主动参与,培养其独立思考和解决问题的能力。
课程目标分解:1. 知识目标:通过讲解和实例演示,让学生掌握C语言的基本知识;2. 技能目标:通过编写“农夫过河”程序,提高学生的编程实践能力;3. 情感态度价值观目标:通过课程教学,激发学生对编程的兴趣,培养其积极思考、勇于探索的精神,以及团队合作能力。
二、教学内容1. C语言基础知识回顾:- 数据类型、变量、常量- 运算符、表达式、语句- 选择结构(if-else)- 循环结构(for、while、do-while)2. 函数定义与调用:- 函数的概念和作用- 函数的定义、声明和调用- 递归函数的原理和应用3. “农夫过河”问题分析:- 问题的描述和规则- 状态表示和状态空间- 搜索策略(深度优先、广度优先)4. 编程实践:- 设计“农夫过河”问题的算法- 编写C语言程序实现算法- 调试和优化程序5. 教学内容安排与进度:- 第一课时:C语言基础知识回顾,引入“农夫过河”问题- 第二课时:函数定义与调用,分析问题并设计算法- 第三课时:编写程序,实现“农夫过河”算法- 第四课时:调试优化程序,总结经验,展示成果教学内容关联教材章节:- 《C语言程序设计》第一章:C语言概述- 《C语言程序设计》第二章:数据类型与运算符- 《C语言程序设计》第三章:控制结构- 《C语言程序设计》第四章:函数- 《C语言程序设计》第十章:算法与程序设计实例教学内容注重科学性和系统性,结合教材章节,使学生能够在掌握C语言基础知识的基础上,学会解决实际问题,提高编程能力。
农夫过河问题
一、题目:农夫过河问题二、目的与要求1、目的:通过布置具有一定难度的实际程序设计项目,使学生进一步理解和掌握课堂上所学各种基本抽象数据类型的逻辑结构、存储结构和操作实现算法,以及它们在程序中的使用方法;使学生掌握分析问题,求解问题的方法并提高学生设计编程实现的能力。
2、要求:基本要求:1.要求利用C\C++语言来完成系统的设计;2.突出C语言的函数特征(以多个函数实现每一个子功能)或者C++语言面向对象的编程思想;3.画出功能模块图;4.进行简单界面设计,能够实现友好的交互;5.具有清晰的程序流程图和数据结构的详细定义;6.熟练掌握C语言或者C++语言的各种操作。
创新要求:在基本要求达到后,可进行创新设计,如系统用户功能控制,改进算法的实现,实现友好的人机交互等等三、问题描述和求解方法:1 、问题描述要求设计实现农夫过河问题(农夫带着一只狼,一只养,一棵白菜,一次只能带一个东西)如何安全过河。
2 、问题的解决方案:可以用栈与队列、深度优先搜索算法及广度优先搜索算法相应的原理去解决问题。
1)实现四个过河对象(农夫、白菜、羊和狼)的状态,可以用一个四位二进制数来表示,0表示未过河,1表示已经过河了。
2)过河的对象必须与农夫在河的同一侧,可以设计函数来判断。
3)防止状态往复,即农夫将一个东西带过去又带回来的情况发生,需将所有可能的状态进行标定。
4)可用深度优先搜索算法及广度优先搜索算法去解题。
四、解题过程1.分析程序的功能要求,划分程序功能模块。
2.画出系统流程图。
3.代码的编写。
定义数据结构和各个功能子函数。
4.程序的功能调试。
5.完成系统总结报告以及使用说明书五、进度安排此次课程设计时间为一周,分以下几个阶段完成:1.选题与搜集资料:每人选择一题,进行课程设计课题的资料搜集。
2.分析与概要设计:根据搜集的资料,进行程序功能与数据结构分析,并选择合适的数据结构、并在此基础上进行实现程序功能的算法设计。
课程设计农夫过河
课程设计农夫过河一、教学目标本章节的教学目标包括以下三个方面:1.知识目标:学生能够理解并掌握“农夫过河”问题的背景、条件和目标,了解相关的数学知识,如线性方程、不等式等。
2.技能目标:学生能够运用所学的数学知识,通过分析和逻辑推理,找到解决问题的方法,并能够进行有效的沟通和合作。
3.情感态度价值观目标:学生能够培养问题解决的兴趣和自信心,培养团队合作和沟通的能力,培养对数学学科的积极态度。
二、教学内容本章节的教学内容主要包括以下几个部分:1.引入“农夫过河”问题的背景和条件,引导学生了解问题的目标和意义。
2.引导学生学习相关的数学知识,如线性方程、不等式等,并通过例题和练习题进行巩固。
3.引导学生运用所学的数学知识,分析和解决“农夫过河”问题,寻找最优解法。
4.通过小组讨论和展示,培养学生的团队合作和沟通能力。
三、教学方法本章节的教学方法主要包括以下几种:1.讲授法:教师通过讲解和演示,引导学生理解和掌握相关的数学知识和解决问题的方法。
2.讨论法:教师学生进行小组讨论,鼓励学生提出问题、分享思路和解决方案。
3.案例分析法:教师提供具体的案例,引导学生运用所学的数学知识进行分析和解决。
4.实验法:教师引导学生进行实验操作,通过实践来加深对数学知识的理解和应用。
四、教学资源本章节的教学资源主要包括以下几种:1.教材:教师准备相关的数学教材,提供理论知识的学习和练习题的练习。
2.参考书:教师提供相关的参考书籍,供学生进一步深入学习和探索。
3.多媒体资料:教师准备相关的多媒体资料,如图片、视频等,用于辅助讲解和演示。
4.实验设备:教师准备相关的实验设备,供学生进行实验操作和实践。
五、教学评估本章节的教学评估主要包括以下几种方式:1.平时表现:教师通过观察和记录学生在课堂上的参与程度、提问回答等情况,评估学生的学习态度和表现。
2.作业:教师通过布置和批改相关的作业,评估学生对知识的理解和应用能力。
3.考试:教师通过安排章节考试或者小测验,评估学生对知识掌握的程度和问题解决的能力。
数据结构课程设计-农夫过河-实验报告.
一、需求分析描述1、针对实现整个过程需要多步,不同步骤中各个事物所处位置不同的情况,可定义一个结构体来实现对四个对象狼、羊、白菜和农夫的表示。
对于起始岸和目的岸,可以用0或者1来表示,以实现在程序设计中的简便性。
2、题目要求给出四种事物的过河步骤,没有对先后顺序进行约束,这就需要给各个事物依次进行编号,然后依次试探,若试探成功,进行下一步试探。
这就需要使用循环或者递归算法,避免随机盲目运算且保证每种情况均试探到。
3、题目要求求出农夫带一只羊,一条狼和一颗白菜过河的办法,所以依次成功返回运算结果后,需要继续运算,直至求出结果,即给出农夫的过河方案。
4、输出界面要求具有每一步中农夫所带对象及每步之后各岸的物体,需要定义不同的数组来分别存储上述内容,并使界面所示方案清晰简洁。
二、系统架构设计1.设计中首先涉及的就是数据类型的定义,首先,定义一个结构体用来存放农夫、狼、羊、白菜的信息。
具体定义为:struct Condition{int farmer;int wolf;int sheep;int cabbage;};定义了一个结构体数组Condition conditions[100],定义状态数组用来记录他们过河的状态0:起始岸;1:目的岸;程序中定义的char action100数组用来存放各个物件以及人过河或返回的说明语句。
2.程序中定义的子函数有:2.1 将狼带到目的岸以及带回起始岸的函数takeWolfOver()和takeWolfBack ();takeWolfOver()函数中将conditions[i+1].wolf=1,白菜、羊的状态不变,同时要有action[i]=" take wolf over."将狼带到目的岸语句;takeWolfBack()函数中将conditions[i+1].wolf=0,白菜、羊的状态不变,同时要有action[i]=" take wolf back."将狼带回起始岸语句。
数据结构课程设计报告(农夫过河)
目录引言 (2)1 问题描述 (2)基本要求 (2)2.1为农夫过河问题抽象数据模型体会数据模型在问题求解中的重要性; (2)2.2设计一个算法求解农夫过河问题,并输出过河方案; (2)3 概要设计 (2)3.1数据结构的设计。
(2)3.1.1农夫过河问题的模型化 (2)3.1.2 算法的设计 (3)4、运行与测试 (5)5、总结与心得 (6)附录 (6)参考文献 (12)引言所谓农夫过河问题是指农夫带一只狼、一只羊和一棵白菜在河南岸, 需要安全运到北岸。
一条小船只能容下他和一件物品, 只有农夫能撑船。
问农夫怎么能安全过河, 当然狼吃羊, 羊吃白菜, 农夫不能将这两种或三种物品单独放在河的一侧, 因为没有农夫的照看, 狼就要吃羊, 而羊可能要吃白菜? 这类问题的实质是系统的状态问题, 要寻求的是从初始状态经一系列的安全状态到达系统的终止状态的一条路径。
1 问题描述一个农夫带一只狼、一棵白菜和一只羊要从一条河的南岸过到北岸,农夫每次只能带一样东西过河,但是任意时刻如果农夫不在场时,狼要吃羊、羊要吃白菜,请为农夫设计过河方案。
基本要求2.1为农夫过河问题抽象数据模型体会数据模型在问题求解中的重要性;2.2设计一个算法求解农夫过河问题,并输出过河方案;3 概要设计3.1 数据结构的设计。
3.1.1农夫过河问题的模型化分析这类问题会发现以下特征:有一组状态( 如农夫和羊在南, 狼和白菜在北) ; 从一个状态可合法地转到另外几个状态( 如农夫自己过河或农夫带着羊过河) ; 有些状态不安全( 如农夫在北, 其他东西在南) ; 有一个初始状态( 都在南) ; 结束状态集( 这里只有一个, 都在北) 。
问题表示: 需要表示问题中的状态, 农夫等位于南P北( 每个有两种可能) 。
可以采用位向量, 4 个二进制位的0P1 情况表示状态, 显而易见, 共24= 16种可能状态。
从高位到低位分别表示农夫、狼、白菜和羊。
骑士巡游数据结构课程设计完成版
目录一.课程设计的目的 (1)二.功能说明 (1)三.详细设计 (2)3.1.功能模块设计 (2)3.1.1.主函数main()的执行流程 (2)3.1.2.创建模块 (2)3.1.3.操作模块 (2)3.1.4.显示模块 (3)3.2.数据结构设计 (3)四.程序实现 (3)4.1.源码分析 (3)4.2.调试结果 (6)4.3.调试时遇到的问题及解决 (6)4.4.时间复杂度分析 (6)4.5.算法的改进设想 (7)结束语 (7)参考文献 (8)一.课程设计的目的1.骑士巡游的求解是一个经典的算法,许多数学家,程序员在不断寻早改善求解方法。
对骑士巡游问题的研究中可包括贪心算法,回溯算法,穷举算法。
本例是通过穷举算法,加深对数据穷举的理解。
2.在对已经走过的路线里,采用标志矩阵进行记录。
标志矩阵的引入利用了数据的线性存储。
3.利用穷举算法,标志矩阵实现简单的骑士巡游算法。
二.功能说明整个实验完成一个骑士巡游算法,本实验中骑士巡游的实现通过穷举举例和标志矩阵。
1.创建模块。
根据输入的行列数创建标志矩阵。
创建标志矩阵显示巡游结果进行巡游2. 操作模块。
输入骑士的初始位置,进行骑士巡游操作。
3. 显示模块。
显示出巡游结果。
图1 功能模块图三. 详细设计3.1.功能模块设计3.1.1. 主函数main()的执行流程1. 在进入main()函数之后立即执行菜单, 输入行列数,本实验中,行列最大11。
2.执行流程如图:图2 主函数main()的流程图3.1.2. 创建模块本模块先要求输入要创建的棋盘的行列数。
程序给出标志矩阵。
3.1.3. 操作模块输入骑士初始位置,进行巡游。
操作模块 显示模块创建模块 骑士巡游表实验程开始 Main ()函数输入命令是否符合条件是否判断命令,完成相应功能结束3.1.4.显示模块现实巡游结果。
3.2.数据结构设计利用标志矩阵,行优先,循序存取,对巡游过的方格标志,通过简单的算法将标志矩阵与棋盘位置进行转换。
趣味数学教案—农夫过河
趣味数学教案—农夫过河-CAL-FENGHAI-(2020YEAR-YICAI)_JINGBIAN农夫过河教学目标1、知识与能力:通过农夫过河的数学逻辑问的题,探讨研究找到解决问题的办法和养成自己动脑动手的解决问题的能力。
2、过程与方法:通过以角色扮演的形式让学生自己动脑动手寻找答案和探讨解决问题的方法。
3、态度价值观:知道数学有很多有趣的东西,培养爱科学的情感。
教师准备1. 数学课件。
2、做“狼、羊、白菜、农夫”头饰。
3、准备四张纸分别写上“狼、羊、白菜、农夫”。
教学过程一、谈话导入介绍我国著名的数学家华罗庚爷爷。
数学家华罗庚生平介绍,主要科学业绩,对数学的贡献等等。
介绍华罗庚爷爷的话。
“数学本身,也是无穷的美妙,认为数学枯燥,是不正确的,就像站在花园外面,说花园枯燥无味一样,只要你踏进大门,随时会发现数学有许多有趣的东西。
”数学并不是几个数字算来算去,它的学问大着呢。
下面这道题能引起你的兴趣吗?二、创设情境1、出示数学问题:有一个农夫带一匹狼、一只羊和一棵白菜过河(从河的东岸到西岸)。
如果没有农夫看管,则狼要吃羊,羊要吃白菜。
但是船很小,只够农夫带一样东西过河。
2、图片演示。
(一条河;一边是对岸;另一边是河岸,有农夫、狼、羊、白菜)三、探究学习1、以小组表演形式(演示出河的位置)和讨论形式解题第一步是什么必须是什么(农夫和羊先过河)第二步是什么(农夫自己回来)第三步是什么2、全班学生汇报交流问题的突破口在——狼与白菜能够共存!农夫、狼、羊、白菜和船组成了这个系统。
系统中各要素是一个整体,都依赖农夫过河;最大的问题是“船很小,只够农夫带一样东西过河”和“没有农夫看管,则狼要吃羊,羊要吃白菜”的冲突。
我们联系已知条件,做了一系列的分析实验,但是比较其他方案不能实现所有要素都安全过河。
最后得出以上方案。
具体描述如下:第一步:把羊带过河,坐船返回;第二步:把狼带过河,带羊返回;第三步:将羊放在这一岸后,带白菜过河;第四步:坐船返回,把羊带过河。
农夫过河数据结构
农夫过河数据结构郑州轻工业学院课程设计任务书题目农夫过河专业、班级计算机科学与技术学号姓名主要内容:一个农夫带着一只狼、一只羊和一棵白菜,身处河的南岸,要把这些东西全部运到北岸。
他面前只有一条小船,船只能容下他和一件物品,另外只有农夫才能撑船。
如果农夫在场,则狼不能吃羊,羊不能吃白菜;否则狼会吃羊,羊会吃白菜。
所以农夫不能留下羊和白菜自己离开,也不能留下狼和羊自己离开,而狼不能吃白菜。
要求给出农夫将所有的东西运过河的方案。
基本要求:编写求解该问题的算法程序,并用此程序上机运行、调试,屏幕显示结果,能结合程序进行分析。
主要参考资料:数据结构严蔚敏完成期限: 2012/6/21指导教师签名:课程负责人签名:年月日郑州轻工业学院本科数据结构课程设计总结报告设计题目:农夫过河学生姓名:系别:计算机与通信工程学院专业:计算机科学与技术班级:计算机科学与技术学号:指导教师:2012年 6 月 21 日2一,设计题目问题描述:一个农夫带着一只狼、一只羊和一棵白菜,身处河的南岸,他要把这些东西全部运到北岸。
他面前只有一条小船,船只能容下他和一件物品,另外只有农夫才能撑船。
如果农夫在场,则狼不能吃羊,羊不能吃白菜;否则狼会吃羊,羊会吃白菜。
所以农夫不能留下羊和白菜自己离开,也不能留下狼和羊自己离开,而狼不能吃白菜。
要求给出农夫将所有的东西运过河的方案。
二,运行环境(软、硬件环境)VC6.0 Windows7系统三,算法设计的思想对于这个问题,我们需要先自动生成图的邻接矩阵来存储,主要方法是先生成各种安全状态结点,存放在顶点向量中;再根据判断两个结点间状态是否可以转换来形成顶点之间的所有边,并把它们保存在邻接矩阵中。
在建立了图的邻接矩阵存储结构后,利用递归深度优先搜索求出从顶点(0,0,0,0)到顶点(1,1,1,1)的一条简单路径,这样做只能搜到一种合理方法,因为深度优先搜索遍历一个图的时候每一个结点只能被访问一次。
骑士游历课程设计报告范文
骑士游历课程设计报告范文一、题目给你一个8某8的棋盘,骑士的开始位置,结束位置,让你求得骑士从开始位置开始揍到结束位置需要最小的步数是多少?(注意,骑士走日字)要求:(1)输入:输入包含多组数据,每一行都是一组开始位置和结束位置,位置由两个字符组成,一个是小写字母(a-h),一个是数字(1-8),起始位置结束位置由一个空格隔开.(2)输出:输出从起始位置到结束位置,骑士所要走过的最小的步数.(3)所设计的数据结构应尽可能节省存储空间。
(4)程序的运行时间应尽可能少。
二、问题分析本程序需要完成如下要求:给一个8某8的棋盘,一骑士从一开始位置按日字行走到一结束位置,所需要的最小的步数是多少。
测试数据输入时应满足:可以输入测试多组数据,且每组数据的第一个数据表示骑士的开始位置,第二个数据表示结束位置;数据输出时应满足:输出的数据为骑士从一开始位置按日字行走到一结束位置所需要的最小的步数。
实现本程序要解决如下几个问题:1、如何表示骑士的开始位置和结束位置2、怎样实现让骑士按日字行走3、如何计算骑士从开始位置到结束位置所走的步数4、如何保证所得步数为最小的步数5、输入多组数据时,每组数据的第一个数据表示骑士的开始位置,第二个数据表示结束位置6、把最小的步数输出解决本程序的问题的关键在于如何让骑士按日字行走,如何计算骑士从开始位置到结束位置所走的步数以及如何保证所得的步数为骑士从开始位置到结束位置所需要的最小的步数,并且可以输入多组数据测试多组最小的步数。
首先,由于棋盘只有8行8列,骑士不能跳到棋盘之外,所以,当开始位置和结束位置为a1,b2或a8,b7或g2,h1或g7,h8时,为特殊情况,不能用算法计算出来,应该单独列举出来,所需要的最小的步数为4步;另外,当不是这几种特殊情况时,从一开始位置到一结束位置可能有好几种走法,相应的所走的步数也可能不相同,应选取其中的最小的数为最小步数。
三、数据结构的选择和概要设计由于,对于一个给定的开始位置,可以选取多个位置作为结束位置,相应的,对于一个给定的结束位置,也可以选取多个位置作为开始位置,所以,数据的逻辑结构可以为图形结构,相应的存储结构也可以选为邻接表,用邻接表来存储骑士的开始位置和结束位置比较方便,而且可以存储多组开始位置和结束位置。
(完整word版)骑士游历java课程设计
数据结构课程设计报告目录1 设计目的与意义 (3)2 系统描述 (3)3 运行环境 (3)4 系统的分析与设计 (3)4.1 程序结构说明 (3)4.2 AccessibleSquare算法实现 (4)4.3 画图类算法实现 (5)4.4 主调用程序的设计和开发 (7)5 系统测试 (7)5.1 游戏初始界面 (8)5.2 游戏以(1,1)为起点运行界面 (8)5.3 游戏以(6,3)为起点界面 (9)5.4 游戏以(6,3)为起点运行界面 (9)6 总结 (10)源程序 (10)1 设计目的与意义Java课程设计是计算机科学与技术专业学生必做的集中实践性环节之一,是学习完《Java程序设计》课程后进行的一次全面的综合练习。
其目的在于通过课程设计,使学生能够得到较系统的技能训练,从而巩固和加深对Java 编程的基础理论知识的理解,培养学生综合运用所学理论解决实际问题的能力,使学生成为具有扎实的计算机理论基础和较强的独立动手能力的复合型、应用型人才。
2 系统描述骑士游历问题是一个古老而著名的问题,它最初是由大数学家Euler提出的。
问题是这样的:国际象棋中的棋子(叫作骑士)在一个空棋盘内移动,问它能否经过64格中的每一格且只经过一次?(骑士按L行移动,即在某方向前进两格接着在与原方向垂直的方向上前进一格)该课程设计要求实现骑士游历问题的求解,并能够演示起始位置在棋盘上任何位置的游历问题的实现。
程序将采用动态的图形演示,使算法的描述更形象、更生动。
本程序采用Applet来编制整个程序,这样既可以加深对算法的实现的了解,也可以进一步熟悉Java图形界面、Applet以及Java语言的命名规范。
骑士游历的课程设计是按照面向对象的思想进行开发,其中主要的类包括AccessibleSquare 类、MyPanel类和KnightsTour类。
其中AccessibleSquare 类主要是算法实现,采用启发式算法;KnightsTour类是主类,或者说是控制类,它完成对算法类和图画类的调用;MyPanel类是画图类用来实现图形化显示结果。
数据结构课程设计报告(农夫过河)
数据结构课程设计报告(农夫过河)第一篇:数据结构课程设计报告(农夫过河)目录引言...................................................2 问题描述..............................................3 基本要求 (3)2.1为农夫过河问题抽象数据模型体会数据模型在问题求解中的重要性;........3 2.2设计一个算法求解农夫过河问题,并输出过河方案;......................3 3 概要设计 (3)3.1 数据结构的设计。
....................................................3 3.1.1农夫过河问题的模型化.............................................3 3.1.2 算法的设计 (4)4、运行与测试 (6)5、总结与心得..........................................7 附录...................................................7 参考文献. (13)引言所谓农夫过河问题是指农夫带一只狼、一只羊和一棵白菜在河南岸, 需要安全运到北岸。
一条小船只能容下他和一件物品, 只有农夫能撑船。
问农夫怎么能安全过河, 当然狼吃羊, 羊吃白菜, 农夫不能将这两种或三种物品单独放在河的一侧, 因为没有农夫的照看, 狼就要吃羊, 而羊可能要吃白菜? 这类问题的实质是系统的状态问题, 要寻求的是从初始状态经一系列的安全状态到达系统的终止状态的一条路径。
1 问题描述一个农夫带一只狼、一棵白菜和一只羊要从一条河的南岸过到北岸,农夫每次只能带一样东西过河,但是任意时刻如果农夫不在场时,狼要吃羊、羊要吃白菜,请为农夫设计过河方案。
基本要求2.1为农夫过河问题抽象数据模型体会数据模型在问题求解中的重要性;2.2设计一个算法求解农夫过河问题,并输出过河方案;概要设计3.1 数据结构的设计。
农夫过河C语言课程设计
农夫过河C语言课程设计一、教学目标本课程的学习目标包括以下三个方面:1.知识目标:学生需要掌握C语言的基本语法、数据类型、运算符、控制结构、函数等核心知识,理解C语言的编程思想和方法,能够独立编写简单的C语言程序。
2.技能目标:学生能够熟练使用C语言编程工具,掌握代码的调试和运行方法,具备自主学习和解决问题的能力。
3.情感态度价值观目标:培养学生对计算机科学的兴趣和热情,提高学生逻辑思维和抽象思维能力,培养学生良好的编程习惯和团队合作精神。
二、教学内容本课程的教学内容主要包括以下几个部分:1.C语言基本语法:数据类型、变量、常量、运算符、表达式等。
2.控制结构:顺序结构、分支结构、循环结构等。
3.函数:函数的定义、调用、参数传递、返回值等。
4.数组和字符串:一维数组、多维数组、字符串的基本操作等。
5.指针:指针的概念、指针的运算、指针与数组、指针与函数等。
6.结构体和联合体:结构体的定义、使用、联合体的定义和使用等。
7.文件操作:文件的打开、关闭、读写等基本操作。
三、教学方法本课程采用多种教学方法,以激发学生的学习兴趣和主动性:1.讲授法:教师讲解C语言的基本语法、概念和原理,引导学生理解并掌握相关知识。
2.案例分析法:通过分析实际案例,让学生了解C语言在实际编程中的应用,提高学生的编程能力。
3.实验法:学生动手编写C语言程序,进行调试和运行,培养学生的实际编程能力。
4.讨论法:学生分组讨论问题,共同解决问题,培养学生的团队合作精神和沟通能力。
四、教学资源本课程所需的教学资源包括:1.教材:《C程序设计语言》(K&R)或《C语言程序设计》(谭浩强)。
2.参考书:《C Primer Plus》、《C和指针》等。
3.多媒体资料:课件、教学视频、编程实例等。
4.实验设备:计算机、编程环境(如Visual Studio、Code::Blocks等)。
5.在线资源:编程、论坛、博客等,供学生自主学习和交流。
c语言骑士游历课程设计
c语言骑士游历课程设计一、课程目标知识目标:1. 理解C语言中数组、循环和条件语句的基本概念和用法;2. 学会使用C语言编写简单的控制台程序,实现骑士游历的逻辑;3. 掌握利用函数实现代码模块化,提高代码的可读性和可维护性。
技能目标:1. 能够运用C语言编写程序,解决骑士游历问题,具备基本的编程能力;2. 能够通过分析问题,设计合理的算法和数据结构,培养问题解决能力;3. 学会使用调试工具,独立排查并修复程序中的错误,提高问题解决效率。
情感态度价值观目标:1. 培养学生对编程的兴趣,激发学习积极性,树立自信心;2. 培养学生的团队合作意识,学会与他人分享、交流编程经验;3. 引导学生认识到编程在实际生活中的应用价值,培养创新精神和实践能力。
课程性质:本课程为实践性较强的编程课程,结合C语言知识,设计具有趣味性的骑士游历项目,帮助学生将所学知识应用于实际项目中。
学生特点:学生具备一定的C语言基础,对编程感兴趣,但编程实践能力和问题解决能力有待提高。
教学要求:注重理论与实践相结合,以项目驱动教学,引导学生通过自主探究和小组合作,完成课程任务。
在教学过程中,关注学生的个体差异,提供有针对性的指导,确保课程目标的达成。
将课程目标分解为具体的学习成果,以便于后续的教学设计和评估。
二、教学内容1. C语言基础知识回顾:数组、循环(for、while)、条件语句(if、else if、else)、函数定义与调用。
2. 骑士游历问题分析:介绍游历问题的背景,分析问题需求,讨论可能的解决方案。
3. 算法设计:讲解深度优先搜索(DFS)、广度优先搜索(BFS)等算法,探讨其在骑士游历问题中的应用。
4. 数据结构选择:学习并应用二维数组、队列、栈等数据结构存储和处理游历路径。
5. 编程实践:根据教材相关章节,编写C语言程序实现骑士游历问题,包括以下内容:- 初始化棋盘和骑士位置;- 实现DFS或BFS算法,寻找所有可能的游历路径;- 打印出所有有效的游历路径。
农夫过河和骑士周游
1:实验要求实验目的掌握图的遍历问题,运用图的遍历算法解决复杂问题。
掌握并应用邻接存储结构和图的深度遍历问题。
培养学习使用图的相关知识解决实际问题的能力。
实验内容问题描述问题描述:农夫携带一只狼,一只羊,一棵白菜从和的左岸到达河的右岸,由于船只较小,农夫每次只能携带一样过河,在无人看管的情况下狼吃羊,羊吃白菜。
:实验输出要求要求输出农夫携带所有东西安全过河的步骤。
2:程序设计分析:实验内容分析农夫需要多次驾船往返于河的左右两岸,农夫每次过河都会使农夫,狼,羊,白菜的位置发生变化。
利用四元组(农夫,狼,羊,白菜)来表示各自所处于河的左岸右岸的位置,0表示河的左岸,1表示河的右岸。
初始状态时(0,0,0,0)都处在河的左岸,终态是(1,1,1,1)四者都处在河的右岸。
共有16种状态,但其中有些状态不安全,删除不安全的状态,将安全的状态按照合理的过河步骤联系起来.(0,0,0,0)(1,0,1,0)(0,0,1,0)(1,1,1,0) (1,0,1,1)(0,1,0,0) (0,0,0,1)(1,1,0,1)(0,1,0,1)(1,1,1,1)安全过河状态图主要函数模块算法分析1:栈的相关函数PSeqStack Init_SeqStack(void) armer,G->vertex[k].wolf,G->vertex[k].sheep,G->vertex[k].vegetable);m=CountAdjoin(G,k);if(m==0) armer,G->vertex[t].wolf,G->vertex[t].sheep,G->vertex[t].vegetable);a=t;t=path[t][1];visited[t]=FALSE;n++;}elsebreak;}printf("\n");}j=l;k=a;}k=path[k][1];}}3:实验结果结果分析:农夫过河的安全步骤:NO1:农夫,狼,羊,白菜都在河的左岸NO2:农夫带羊到河的右岸NO3:农夫回到河的左岸NO4:农夫带狼到河的右岸或者农夫带白菜到河的右岸NO5:农夫带羊回到河的左岸或者农夫带羊回到河的左岸NO6:农夫带狼到河的右岸NO7:农夫回到河的左岸NO8:农夫带羊到和的右岸4:实验心得通过农夫过河的实验,使我初步了解解决一些复杂较难问题的思路和掌握了解决问题的方法。
c语言课课程设计农夫过河
c语言课课程设计农夫过河一、教学目标本章节的教学目标旨在让学生掌握C语言的基本语法和编程思想,通过“农夫过河”的案例,培养学生解决实际问题的能力。
具体目标如下:1.知识目标:学生能理解C语言的基本数据类型、运算符、控制结构等语法知识。
2.技能目标:学生能运用C语言编写简单的程序,解决实际问题。
3.情感态度价值观目标:培养学生热爱编程,勇于探索,积极解决问题的精神。
二、教学内容本章节的教学内容以“农夫过河”案例为主线,贯穿C语言的基本语法和编程思想。
教学大纲如下:1.C语言简介:介绍C语言的历史、特点和应用领域。
2.基本数据类型和运算符:讲解整型、浮点型、字符型数据及其运算符。
3.控制结构:讲解顺序结构、分支结构、循环结构。
4.函数:讲解函数的定义、声明和调用。
5.数组和指针:讲解一维、二维数组以及指针的概念和应用。
6.农夫过河案例:利用所学知识编写程序,解决农夫过河问题。
三、教学方法本章节采用多种教学方法,以激发学生的学习兴趣和主动性:1.讲授法:讲解C语言的基本语法和编程思想。
2.案例分析法:通过分析“农夫过河”案例,引导学生运用所学知识解决问题。
3.实验法:让学生动手编写程序,加深对知识的理解和运用。
4.讨论法:分组讨论,培养学生的团队协作能力和沟通能力。
四、教学资源为了支持教学内容和教学方法的实施,丰富学生的学习体验,我们将提供以下教学资源:1.教材:《C语言程序设计》2.参考书:《C语言 Primer》3.多媒体资料:教学PPT、视频教程4.实验设备:计算机、编程环境5.在线资源:编程论坛、开源项目、在线教程等。
五、教学评估本章节的教学评估将采取多元化方式,以全面、客观、公正地评估学生的学习成果。
评估方式包括:1.平时表现:考察学生在课堂上的参与度、提问回答、团队协作等情况。
2.作业:布置课后编程作业,检查学生对知识的掌握和运用能力。
3.考试:期末进行C语言编程考试,检验学生的综合运用能力。
过河问题——数据结构课程设计
课题27:有一人要将自己的兔子、蔬菜、狐狸等三件物品运过河。
但过河所用的船每次只能装其中的两件,而这三件物品有存在一定的制约关系:兔子不能单独和狐狸以及不能和蔬菜在一起,因为狐狸要吃兔子,兔子也能吃蔬菜,试构造出问题模型,并编程实现这一问题的求解。
1.模型描述:由于涉及兔子、蔬菜、狐狸这三件物品并且三者之间存在一定的制约关系,即食与被食的关系,因此可以用一个无向图来表示三者之间的关系:1)用定点表示兔子,蔬菜和狐狸;2)用边来表示三者之间的制约关系,如果Pi 与Pj 之间有制约关系,则从顶点i 到顶点j 有一条边。
狐狸 兔子 蔬菜①——②——③2.算法设计:1)问题分析:船一次只能运两件,所以无法一次将三件物品运过河,而存在制约关系的物品又不能在一起,则不能在一起的物品也就不能被一起运过河。
2)用邻接矩阵来存储图,两定点之间有边的,相应位置初始化为1;没有边的,相应位置初始化为0;对角线上元素初始化为-1.狐狸 兔子 蔬菜蔬菜兔子狐狸 ⎪⎪⎪⎭⎫ ⎝⎛1-1011-1011-3)由于三样物品不能一起运过河,则要分批运。
每次只能运两件,而当人在船上时,则显然可以制约物品间的食与被食,则可以从三件物品先选其中的两件(不管是否有制约关系)运过河并判断这两件是否有制约关系,如果没有,则直接回来运剩下的一件物品,否则将其中一件运回与剩下的一件一起运过河。
3.程序代码和运行结果:#include<iostream.h>#include<string.h>class G{public:G(); //初始化函数void create(); //生成图void print(); //以邻接矩阵的方式输出图int method_of_shipment(); //将物品运过河的方法int adjacency_matrix[3][3]; //邻接矩阵,用于存储图};G::G(){for(int i=0;i<3;i++)for(int j=0;j<3;j++){if(i==j) adjacency_matrix[i][j]=-1; //将邻接矩阵对角线上的元素初始化为-1else adjacency_matrix[i][j]=0; //将邻接矩阵非对角线上元素初始化为0}}void G::create(){int i,j; //i,j分别表示元素的行下标和列下标cout<<"请输入有制约关系的物品所对应的编号并以4结束:\n";cin>>i>>j; //依次从键盘输入i,jwhile(i<=3 && j<=3) //循环生成图{adjacency_matrix[i-1][j-1]=1; //将下标为i,j元素值变为1cin>>i>>j;}}void G::print(){cout<<"存储图的邻接矩阵示意图:\n";cout<<" 狐狸"<<"兔子"<<"蔬菜"; //输出各列对映的物品cout<<'\n';char Res[3][5]={"狐狸","兔子","蔬菜"}; //用于存储编号所对应的物品for(int i=0;i<3;i++){cout<<Res[i]<<””;for(int j=0;j<3;j++) cout<<adjacency_matrix[i][j]<<" ";cout<<'\n';}cout<<'\n';}int G::method_of_shipment(){char Res[3][5]={"狐狸","兔子","蔬菜"}; //用于存储编号所对应的物品cout<<"可用如下几种方法中的一种顺利将物品运过河:\n";cout<<'\n';for(int i=0;i<3;i++){for(int j=i+1;j<3;j++){cout<<"先将"<<Res[i]<<"和"<<Res[j]<<"运过河,";if(adjacency_matrix[i][j])cout<<"再将"<<Res[i]<<"运回,与"<<Res[3-i-j]<<"一起运过河"<<'\n';else cout<<"直接回来再将"<<Res[3-i-j]<<"运过河"<<'\n';cout<<'\n';}}cout<<'\n';return 1;}int main(){G g; //生成对象gg.create();g.print();g.method_of_shipment();return 1;}4.总结:本题是用C++编写的程序,定义了一个图类,用临接矩阵来存储图结构,以二维数组来表示邻接矩阵,因而程序比较简洁,主体解决方法采用了先二后一的方法将三件物品运过河,先选三件物品中的两件运过河并判断这两件是否有制约关系,如果没有,则直接回来运剩下的一件物品,否则将其中一件运回与剩下的一件一起运过河。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1:实验要求1.1实验目的掌握图的遍历问题,运用图的遍历算法解决复杂问题。
掌握并应用邻接存储结构和图的深度遍历问题。
培养学习使用图的相关知识解决实际问题的能力。
1.2实验内容问题描述问题描述:农夫携带一只狼,一只羊,一棵白菜从和的左岸到达河的右岸,由于船只较小,农夫每次只能携带一样过河,在无人看管的情况下狼吃羊,羊吃白菜。
1.3:实验输出要求要求输出农夫携带所有东西安全过河的步骤。
2:程序设计分析2.1:实验内容分析农夫需要多次驾船往返于河的左右两岸,农夫每次过河都会使农夫,狼,羊,白菜的位置发生变化。
利用四元组(农夫,狼,羊,白菜)来表示各自所处于河的左岸右岸的位置,0表示河的左岸,1表示河的右岸。
初始状态时(0,0,0,0)都处在河的左岸,终态是(1,1,1,1)四者都处在河的右岸。
共有16种状态,但其中有些状态不安全,删除不安全的状态,将安全的状态按照合理的过河步骤联系起来.(0,0,0,0)(1,0,1,0)(0,0,1,0)(1,1,1,0) (1,0,1,1)(0,1,0,0) (0,0,0,1)(1,1,0,1)(0,1,0,1)(1,1,1,1)安全过河状态图2.2主要函数模块算法分析1:栈的相关函数PSeqStack Init_SeqStack(void) //栈的初始化int Empty_SeqStack(PSeqStack s) //判断栈是否为空栈非空1表示栈空void Push_SeqStack(PSeqStack s,int x) //入栈int Pop_SeqStack(PSeqStack s,int *x) //出栈int Size_SeqStack(PSeqStack s) //顺序栈中元素的个数void Destroy_SeqStack(PSeqStack *S) //销毁栈2,:求结点直接后继结点个数的函数int CountAdjoin(MGraph *G,int u)3:查找状态(f,w,s,v)在无向图中的位置的函数int located(MGraph *G,int f,int w,int s,int v)4:结点值安全状态判断函数int if_safe(int f,int w,int s,int v)5:判断农夫过河的两个状态是否是相邻的函数int if_connected(MGraph *G,int i,int j)6:创建农夫过河状态的无向图void Creat_MGraph(MGraph *G)7:广优度先遍历遍历所有从状态下标u到状态下标v的路径函数void BFS_path(MGraph *G,int u,int v)8:输出所有从状态下标为u到状态下标为v的所有简单路径void print_path(MGraph *G,int u,int v)2.3部分函数源代码path[u][m] 为状态下标u的直接后继状态下标 m表示状态下标u的直接后继结点个数:int path[MaxVertexNum][MaxVertexNum];主要结构:typedef struct{int farmer;int wolf;int sheep;int vegetable;}vertexType; //顶点结点类型typedef struct{vertexType vertex[MaxVertexNum];int edges[MaxVertexNum][MaxVertexNum];int vertexNum;}MGraph; //邻接矩阵存储结构类型typedef struct{int data[MAXSIZE];int top; //栈顶}SeqStack,*PSeqStack;void BFS_path(MGraph *G,int u,int v) //深度优先遍历从状态下标u到状态下标v{int i,j,m,n;PSeqStack S;S=Init_SeqStack();Push_SeqStack(S,v);visited[u]=TRUE; //改变路径头结点的访问标志为TRUEPush_SeqStack(S,u);while(!Empty_SeqStack(S)){Pop_SeqStack(S,&u);m=1;for(i=0;i<G->vertexNum;i++) //判定后继结点的个数及将其后继结点访问标志置TRUE{if(G->edges[u][i] && !visited[i]){path[u][m]=i; //将下标为U的后继结点下标赋给path[u][m] m用来记录直接后继结点的个数visited[i]=TRUE;m++;}}for(j=1;j<=m;j++){n=path[u][j];if(n!=v) //判断结束标志如果数的后继结点下标与要找的一条路径最后一个结点的下标不一样则将后继元素下标入栈Push_SeqStack(S,n);else //或者将栈中的最后一个元素出栈Pop_SeqStack(S,&u);}while(Size_SeqStack(S)>2) //栈中元素个数大于2 则一直出栈{Pop_SeqStack(S,&u);m=1;for(i=0;i<G->vertexNum;i++){if(G->edges[u][i] && !visited[i])//path[u][m] 为状态下标u的直接后继状态下标 m表示状态下标u的后继结点个数{path[u][m]=i;visited[i]=TRUE;m++;}}}}Destroy_SeqStack(&S); //销毁栈}void print_path(MGraph *G,int u,int v) //输出所有从状态下标为u到状态下标为v的所有简单路径{int n,k,i,j,m,t,a,l;k=u;j=1;visited[u]=FALSE; //改变第一个结点的访问标志path[v][1]=-1; //将一条路径的最后一个顶点的后继结点下标置为无穷大while(k!=-1){printf("\t\tNO%d:(%d,%d,%d,%d)\n",j++,G->vertex[k].farmer,G->vertex[k].wolf,G->vertex[k].sheep,G->vertex[k].vegetable);m=CountAdjoin(G,k);if(m==0) //结束条件后继结点个数为零break;if(m!=1){for(i=m;i>0;i--) //输出某个结点后的所有分支后继结点{t=k;t=path[t][i];n=0;l=j;while(t!=-1){if(n<=1) //(某个结点分支后继结点个数)//用于转换输出另外一条分支后继结点的判断条件{printf("\tNO%d:(%d,%d,%d,%d)",l++,G->vertex[t].farmer,G->vertex[t].wolf,G->vertex[t].sheep,G->vertex[t].vegetable);a=t;t=path[t][1];visited[t]=FALSE;n++;}elsebreak;}printf("\n");}j=l;k=a;}k=path[k][1];}}3:实验结果结果分析:农夫过河的安全步骤:NO1:农夫,狼,羊,白菜都在河的左岸NO2:农夫带羊到河的右岸NO3:农夫回到河的左岸NO4:农夫带狼到河的右岸或者农夫带白菜到河的右岸NO5:农夫带羊回到河的左岸或者农夫带羊回到河的左岸NO6:农夫带狼到河的右岸NO7:农夫回到河的左岸NO8:农夫带羊到和的右岸4:实验心得通过农夫过河的实验,使我初步了解解决一些复杂较难问题的思路和掌握了解决问题的方法。
通过该实验的代码编程过程中也进一步提高了我对c语言的掌握,掌握了栈,深度广度遍历的算法,也提高了我对算法的学习设计能力,同时提高了编程调试的能力,使我遇到那些逻辑上的错误,能通过自己一点一点的调试,搜寻逻辑错误所在处。
在编程调试中遇相关的问题时,让我明白遇到问题不可怕,怕的是遇到问题不想解决或者没有解决问题恒定的决心,即使一些问题在困难,当时对遇到的可能丝毫没有头绪,只要一点点的对问题剖析,哪怕在困难的问题也会被解决。
实验二1:实验要求:1.1:实验目的提高分析设计解决问题的能力,并掌握选择策略的图的深度优先搜索等先关的知识。
1.2:实验内容问题描述马随机放在国际象棋8*8的方格中,马按照走马的规则进行移动,要求马走过每个格走过仅走过一次并且每个格都走过,编程求输出马走过的路径1.3: 实验输出输出骑士周游的路径2:程序设计分析2.1:实验内容分析在国际象棋的棋盘上,马共有八个可能的跳跃方向。
设置一组坐标增量来描述这八个条约方向:①(1,2)②(2,1)③(2,-1)④(1,-2)⑤(-1,-2)⑥(-2,-1)⑦(-2,1)⑧(-1,2)2.2:主要算法模块分析void go(int n,int x,int y) 递归算法模块2.3: 主要源代码#include <stdio.h>#define N 8int ditu[N][N] = //棋盘初始化所有点为零{{0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0}};int path[N][N]; //记录周游路径int flag=0; //结束标记int incX[]={1,2,2,1,-1,-2,-2,-1}; //指示方向横坐标int incY[]={-2,-1,1,2,2,1,-1,-2}; //指示方向纵坐标void go(int n,int x,int y){if (n>=(N*N)) //判断是否走完整个地图{flag=1;path[x][y]=n;}if (flag==1) //递归结束标志return;path[x][y]=n; //将骑士走的路径记录ditu[x][y]=1; //标记坐标(x,y)点走过for (int i=0;i<8;i++) //8方向探路if ((((x+incX[i])>=0) && ((x+incX[i])<N)) && (((y+incY[i])>=0) && ((y+incY[i])<N)) && (ditu[x+incX[i]][y+incY[i]]==0))go(n+1,x+incX[i],y+incY[i]); //递归周游ditu[x][y] = 0; //8个方向中如果探测方向不是合适的落马点则清除马走过的标记return;}void main(){printf("骑士从棋盘左上角开始的周游路径\n");精品文档go(1,0,0); //设置从0,0开始出发for(int i=0;i<N;i++) //输出路径{for(int j=0;j<N;j++){printf("%4d",path[i][j]);}printf("\n");}}3:实验结果4:实验心得通过该实验让我掌握了数据结构进一步了解,对图的深度优先遍历算法的由来更深的理解与体会,对骑士周游问题有自己的见解和体会。