野蛮人过河问题c语言程序,野蛮人过河问题算法说明(9页)-原创力文档

野蛮人过河问题算法说明

问题说明

有3个传教士和3个野蛮人来到河边,打算乘一只船从左岸渡到右岸。该船的负载能力为2人,在任何时刻如果野蛮人人数超过传教士人数,野蛮人就会把传教士吃掉。他们怎样才能用这条船安全让所有人都渡过河。

二. 算法说明

采用递归算法。因为每次过河都要遵循几个约定,一为两边岸上野蛮人的数量必须大于传教士的数量,二为船上最多只能装两个人,所以采用递归算法不断嵌套循环模拟每次过河的过程,同时加上若干递归中止返回条件,则可以推得过河的方法。

数据结构

船结构:即表示船上野蛮人和传教士的个数

typedef struct Boat

{

int numX; /// 传教士个数

int numY; /// 野蛮人个数

}Boat;

从左岸到右岸时船上装的人的种类,有3种,即2个野人和0个传教士,0个野人和2个传教士,1个野人和1个传教士。

Boat LtoR[3]={{2,0},{0,2},{1,1}};

从右岸回左岸时船上装的人的种类,有2种,即1个野人或1个传教士

Boat RtoL[2]={{1,0},{0,1}};

递归函数1: int fnPassRiver1(x1,y1,x2,y2)

表示每次由一个野蛮人驾船从右岸回左岸后,再向右过河的过程

递归函数2: int fnPassRiver2(x1,y1,x2,y2)

表示每次由一个传教士驾船从右岸回左岸后,再向右过河的过程

具体算法

第一次过河时,有三种情况,即2个野人和0个传教士,0个野人和2个传教士,1个野人和1个传教士,所以在主函数中用参数是k的三重for循环,确定整体过河框架。在接下来的从左向右的过河之前,存在两种可能,即驾船从右边回来的是野蛮人或传教士,因此用两个递归函数fnPassRiver1()和fnPassRiver2()分类。

函数fnPassRiver1()和fnPassRiver2()的内容相似,即先判断递归中止条件,若满足三个条件中的任意一个,都跳出此次循环,回到上一级递归;若不满足,则进入下一级循环,此时改变了函数fnPassRiver1(x1,y1,x2,y2)和fnPassRiver2(x1,y1,x2,y2)中的传递参数x1,y1,x2,y2,改变的依据是数组LtoR[3]中的三组值。具体的说,在函数fnPassRiver1()中依次进行三个递归调用,即当一个野人驾船回左岸后带上另一个野人回右岸,调用下一级递归函数;当一个野人驾船回左岸后带上一个传教士回右岸,调用下一级递归函数;当一个野人驾船回左岸后此野人下船,同时另外两个传教士上船回右岸,调用下一级递归函数。同理,在函数fnPassRiver2()中依次进行三个递归调用,即当一个传教士驾船回左岸后带上另一个传教士回右岸,调用下一级递归函数;当一个传教士驾船回左岸后带上一个野人回右岸,调用下一级递归函数;当一个传教士驾船回左岸后此传教士下船,同时另外两个野人上船回右岸,调用下一级递归函数。

经过不断的递归调用最终实现过河全过程。

源程序

(见下页)

源程序

#include

typedef struct Boat /// 船结构,即表示船上野蛮人和传教士的个数

{

int numX; /// 传教士个数

int numY; /// 野蛮人个数

}Boat;

Boat LtoR[3]={{2,0},{0,2},{1,1}}; ///从左岸到右岸时船上装的人的种类,有3种

///2个野人和0个传教士,0个野人和2个传教士,1个野人和1个传教士

Boat RtoL[2]={{1,0},{0,1}}; ///从右岸回左岸时船上装人的种类,有2种

///1个野人或1个传教士

int fnPassRiver1(x1,y1,x2,y2); ///递归函数,表示每次由一个野蛮人驾船从右岸回左岸

int fnPassRiver2(x1,y1,x2,y2); ///递归函数,表示每次由一个传教士驾船从右岸回左岸

main()

{

int x1,y1,x2,y2; /// x1左岸野蛮人个数,y1左岸传教士个数;x2右岸野蛮人个数,y2右岸传教士个数

int k;

printf(" 左岸 右岸

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值