注:本文首次载于本人的QQ空间,所以这里属于原创转帖
/*********************************************狼羊草*********************************************************/
/***********作者:紫数**************************1.0版完成日期:2009-4-19*******************************/
问题描述是一个农夫带着一只羊、一头狼和一捆草过河。狼要吃羊,羊要吃草,如果农夫不在的话。船上一次只能运一样东西。农夫应该怎样运,才能使羊不被狼吃,草不被羊吃。
这个问题大家小时候一定都做过,现在我要用程序来实现,让计算机搜索所有可能的运法并给出正确的解答。这个问题看似简单,可真要做起来却又不知从何下手。我们先简化一下问题。让用户给出每步操作,然后计算机输出结果,如果失败或成功则给出判定。
现实经验告诉我们,自上而下设计才能提高效率。可是怎么走出第一步是困难所在。我们要输入的是操作,即移动船,装上某物,卸下某物。计算机输出的是三个位置的物品信息(岸A、岸B、船)、船的位置、判定信息。整个系统的信息有:三个位置的物品的信息、船的位置。这样顶层结构就设计好了。
接下来考虑数据结构或者对于每一步操作的具体实现。先考虑哪一个呢?先试试数据结构,因为在同一个位置处,物品是没有先后次序的,所以可以定义如下结构体:
struct items
{
enum goodsenum goods[3];
int num;
int capacity;
};
其中:
enum goodsenum
{
wolf,lamb,grass
};
还有就是船的位置int boatPosition,无非两种:A和B,分别记为1和2(注意,我之所以不用0和1是为了强制显式表达)。
然后……可以了!然后是对每一步操作的具体实现:
1.移动船:if(boatPosition==1)boatPosition=2;else boatPosition=1;
2.装上货物:loadGoods(enum goodsenum)
我们首先要判断船是否为空。如果非空,不执行任何动作;如果空,则进一步判断,岸上是否有该货物,有的话才能装上,否则不执行任何动作。
当执行动作时,岸上货物数量减一,货物数组里拿掉一个元素。同时船上货物数量加一,加上这个元素。
3.卸下货物:unloadGoods()
判断船是否为非空,如果非空,卸下货物,否则不执行任何动作。
当执行动作时,岸上货物数量加一,货物数组里增加一个元素。同时船上货物数量减一,没有元素。
执行完1或2或3后,系统要进行一次判断,判断结果有三种:失败(狼吃了羊或羊吃了草),运行(什么事也没发生),完成(运送成功)。先判定是否完成,如果狼羊草全在B岸且船在B岸则完成,如果没完成,则判断是否失败,如果狼和羊同在一边且船(农夫)在另一边或羊和草同在一边且船(农夫)在另一边则失败,如果没失败,则判定为运行。
最后说明一下初始条件,A岸有全部货物,B岸什么也没有,船在A岸。
事实上,至此,程序已经写成了。^_^ 。
/**************** wolf.c *****************************/
/*************Turbo C 2.0编译通过 ****************/
#include<stdio.h>
struct items
{
enum goodsenum goods[3];
int num;
int capacity; /*****容量,其实就这个问题而言可以不需要*****/
};
enum goodsenum
{
wolf,lamb,grass
};
int boatposition=1;
struct items bank[2]={wolf,lamb,grass,3,3,0,0,0,0,3},boat={0,0,0,0,1};
/*********** 一般来说不建议用全局变量,但这里为了便于理解……**************/
void moveBoat(); /**** 移动船 *****/
void loadGoods(enum goodsenum); /****装上货物******/
void unloadGoods(); /*****卸下货物*****/
void outputMessage(); /****输出船和岸的信息*****/
int hasWolf(int position); /****判断某处是否有狼***/
int hasLamb(int position); /*******判断某处是否有羊********/
int hasGrass(int position); /******判断某处是否有草*********/
int isLose(); /*****判断是否失败,是则返回1,否则返回0******/
/************* 主函数 ****************/
int main()
{
char operation;
outputMessage(); /************输出初始信息******************/
while(bank[1].num<3) /**** 如果没有全部运到对岸则继续下去 *****/
{
operation=getch(); /**********获取按键**************/
switch(operation)
{
case 'm':moveBoat();break; /********** "m" 键对应移动船**************/
case 'l':loadGoods(lamb);break;