问题描述

一个农夫在河边带了一只狼、一只羊和一颗白菜,他需要把这三样东西用船带到河的对岸。然而,这艘船只能容下农夫本人和另外一样东西。如果农夫不在场的话,狼会吃掉羊,羊也会吃掉白菜。请编程为农夫解决这个过河问题。

问题分析

根据问题描述可知,该问题涉及的对象较多,而且运算步骤也较为复杂,因此,在使用C语言实现时,首先需要将具体问题数字化。

由于整个过程的实现需要多步,而不同步骤中各个事物所处的位置不同,因此可以定义一个二维数组或者结构体来表不四个对象狼(wolf)、羊(goat)、白菜(cabbage)和农夫(farmer)。对于东岸和西岸,可以用east和west表示,也可以用0和1来表示, 以保证在程序设计中的简便性。

题目要求给出四种事物的过河步骤,没有对先后顺序进行约束,这就需要给各个事物依次进行编号,然后依次试探,若试探成功,再进行下一步试探。因此,解决该问题可以使用循环或者递归算法,以避免随机盲目运算而且保证每种情况都可以试探到。

题目要求求出农夫带一只羊,一条狼和一颗白菜过河的所有办法,所以依次成功返回运算结果后,需要继续运算,直至求出所有结果,即给出农夫不同的过河方案。

算法设计

本程序使用递归算法,定义二维数组int a[N][4]存储每一步中各个事物所处的位置。二维数组的一维下标表示当前进行的步骤,第二维下标可能的取值为0〜3,在这里规定它与四种事物的具体对应关系为:0——狼、1——羊、2——白菜、3——农夫。接着再将东岸和西岸数字化,用0表示东岸,1表示西岸,该信息存储在二维数组的对应元素中。

定义Step变量表示渡河的步骤,则成功渡河之后,a数组中的存储状态为:

a[Step][0]  1

a[Step][1]  1

a[Step][2]  1

a[Step][3]  1

因为成功渡河后,狼、羊、白菜和农夫都在河的西岸,因此有:

a[Step][0]+a[Step][1]+a[Step][2]+a[Step][3]=4

题目中要求狼和羊、羊和白菜不能在一起,因此若有下述情况出现:

a[Step][1]!=a[Step][3] && (a[Step][2]==a[Step][1] || a[Step][0]=a[Step][1])

则发生错误,应返回操作。

在程序实现时,除了定义a数组来存储每一步中各个对象所处的位置以外,再定义一维数组b[N]来存储每一步中农夫是如何过河的。

程序中实现递归操作部分的核心代码为:

for(i=-1; i<=2; i++)

{

b[Step]=i;

memcpy(a[Step+1], a[Step], 16);  /*复制上一步状态,进行下一步移动*/

a[Step+1][3]=1-a[Step+1][3];  /*农夫过去或者回来*/

if(i == -1)

{

search(Step+1);  /*进行第一步*/

}

else

if(a[Step][i] == a[Step][3])  /*若该物与农夫同岸,带回*/

{

a[Step+1][i]=a[Step+1][3];  /*带回该物*/

search(Step+1);  /*进行下一步*/

}

}

每次循环从-1到2依次代表农夫渡河时为一人、带狼、带羊、带白菜通过,利用语句“b[Step] = i”分别记录每一步中农夫的渡河方式,语句“a[Step+1][i] = a[Step+1][3]”是利用赋值方式使该对象与农夫一同到对岸或者回到本岸。若渡河成功,则依次输出渡河方式。“i<=2”为递归操作的界限,若i=2时仍无符合条件的方式,则渡河失败。

上面代码表示若当前步骤能使各值均为1,则渡河成功,输出结果,进入回归步骤。若当前步骤与以前的步骤相同,则返回操作,代码如下:

if(memcmp(a[i],a[Step],16) == 0)

{

return 0;

}

若羊和农夫不在一块而狼和羊或者羊和白菜在一块,则返回操作,判断代码如下:

if(a[Step][1]!=a[Step][3] && (a[Step][2] == a[Step][1] || a[Step][0] == a[Step][1]))

{

return 0;

}

下面是完整的代码:

#include

#include

#include

#define N 15

int a[N][4];

int b[N];

char *name[]=

{

"        ",

"and wolf",

"and goat",

"and cabbage"

};

int search(int Step)

{

int i;

/*若该种步骤能使各值均为1,则输出结果,进入回归步骤*/

if(a[Step][0]+a[Step][1]+a[Step][2]+a[Step][3] == 4)

{

for(i=0; i<=Step; i++)  /*能够依次输出不同的方案*/

{

printf("east: ");

if(a[i][0] == 0)

printf("wolf  ");

if(a[i][1] == 0)

printf("goat  ");

if(a[i][2] == 0)

printf("cabbage  ");

if(a[i][3] == 0)

printf("farmer  ");

if(a[i][0] && a[i][1] && a[i][2] && a[i][3])

printf("none");

printf("            ");

printf("west: ");

if(a[i][0] == 1)

printf("wolf  ");

if(a[i][1] == 1)

printf("goat  ");

if(a[i][2] == 1)

printf("cabbage  ");

if(a[i][3] == 1)

printf("farmer  ");

if(!(a[i][0] || a[i][1] || a[i][2] || a[i][3]))

printf("none");

printf("\n\n\n");

if(i

printf("                      the %d time\n",i+1);

if(i>0 && i

{

if(a[i][3] == 0)  /*农夫在本岸*/

{

printf("                  ----->  farmer ");

printf("%s\n", name[b[i] + 1]);

}

else      /*农夫在对岸*/

{

printf("

printf("%s\n", name[b[i] + 1]);

}

}

}

printf("\n\n\n\n");

return 0;

}

for(i=0; i

{

if(memcmp(a[i],a[Step],16) == 0)  /*若该步与以前步骤相同,取消操作*/

{

return 0;

}

}

/*若羊和农夫不在一块而狼和羊或者羊和白菜在一块,则取消操作*/

if(a[Step][1]!=a[Step][3] && (a[Step][2] == a[Step][1] || a[Step][0] == a[Step][1]))

{

return 0;

}

/*递归,从带第一种动物开始依次向下循环,同时限定递归的界限*/

for(i=-1; i<=2; i++)

{

b[Step]=i;

memcpy(a[Step+1], a[Step], 16);  /*复制上一步状态,进行下一步移动*/

a[Step+1][3]=1-a[Step+1][3];  /*农夫过去或者回来*/

if(i == -1)

{

search(Step+1);  /*进行第一步*/

}

else

if(a[Step][i] == a[Step][3])  /*若该物与农夫同岸,带回*/

{

a[Step+1][i]=a[Step+1][3];  /*带回该物*/

search(Step+1);  /*进行下一步*/

}

}

return 0;

}

int main()

{

printf("\n\n            农夫过河问题,解决方案如下:\n\n\n");

search(0);

return 0;

}

运行结果:

农夫过河问题,解决方案如下:

east: wolf  goat  cabbage  farmer              west: none

the 1 time

east: wolf  cabbage              west: goat  farmer

the 2 time

east: wolf  cabbage  farmer              west: goat

the 3 time

----->  farmer and wolf

east: cabbage              west: wolf  goat  farmer

the 4 time

east: goat  cabbage  farmer              west: wolf

the 5 time

----->  farmer and cabbage

east: goat              west: wolf  cabbage  farmer

the 6 time

east: goat  farmer              west: wolf  cabbage

the 7 time

----->  farmer and goat

east: none            west: wolf  goat  cabbage  farmer

east: wolf  goat  cabbage  farmer              west: none

the 1 time

east: wolf  cabbage              west: goat  farmer

the 2 time

east: wolf  cabbage  farmer              west: goat

the 3 time

----->  farmer and cabbage

east: wolf              west: goat  cabbage  farmer

the 4 time

east: wolf  goat  farmer              west: cabbage

the 5 time

----->  farmer and wolf

east: goat              west: wolf  cabbage  farmer

the 6 time

east: goat  farmer              west: wolf  cabbage

the 7 time

----->  farmer and goat

east: none            west: wolf  goat  cabbage  farmer

java农夫过河_C语言实现农夫过河代码及解析相关推荐

  1. 判断魔方阵c语言程序设计_C语言实现魔方阵代码及解析

    原标题:C语言实现魔方阵代码及解析 问题描述 编写程序,实现如下表所示的5-魔方阵. 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 1 ...

  2. java 素数 五行_c语言动态烟花小程序代码

    你应该用 点击详情.了解更多! 详情 史蒂芬孙 2018-12-19 00:54 0评论 0赞同 去网上搜索:C语言经典一百例 详情 多面体 2018-09-18 17:25 0评论 10赞同 我们开 ...

  3. java梅森素数,C语言求梅森素数代码及解析

    问题描述 梅森数(Mersenne Prime)指的是形如2n-1的正整数,其中指数n是素数,即为Mn.如果一个梅森数是素数,则称其为梅森素数.例如22-1=3.23-1=7都是梅森素数. 当n=2, ...

  4. 真分数c语言,C语言列出真分数序列代码及解析

    原标题:C语言列出真分数序列代码及解析 按递增顺序依次列出所有分母为60,分子小于60的最简分数. 分子.分母只有公因数1的分数叫做最简分数或者说分子和分母是互质数的分数,叫做最简分数,又称既约分数, ...

  5. C语言过河问题主函数,c,c++_C语言踩石头过河问题,用DFS搜索递归了17万次但是没报错,请问是什么原因?,c,c++,算法 - phpStudy...

    C语言踩石头过河问题,用DFS搜索递归了17万次但是没报错,请问是什么原因? 这是原题目,后面附上我的代码,刚刚接触DFS,不是很熟练,求教育--谢谢!!!TUT 这是题目,我大概概括一下 用'※'和 ...

  6. 语言小型心形图案代码_c语言心形告白代码实现

    c语言心形告白代码实现 1.彩色告白 include include include include define U 0.1 define V 0.053 void SetColor(unsigne ...

  7. c++心形代码_c语言心形告白代码实现

    c语言心形告白代码实现 1.彩色告白 include include include include define U 0.1 define V 0.053 void SetColor(unsigne ...

  8. c语言怎么表示小写字母a到z,C++_C语言字符串快速压缩算法代码,通过键盘输入一串小写字母(a~z - phpStudy...

    C语言字符串快速压缩算法代码 通过键盘输入一串小写字母(a~z)组成的字符串. 请编写一个字符串压缩程序,将字符串中连续出席的重复字母进行压缩,并输出压缩后的字符串. 压缩规则: 1.仅压缩连续重复出 ...

  9. JAVA、PHP身份证、统一社会信用代码算法解析验证

    JAVA.PHP身份证算法解析验证 JAVA身份证号算法解析验证(待更新) JAVA统一社会信用代码算法解析验证(待更新) PHP统一社会信用代码算法解析验证 JAVA.PHP身份证算法解析: 其实上 ...

最新文章

  1. web浏览器_如何在iPhone和iPad上更改默认的Web浏览器
  2. pom配置之:distributionManagementsnapshot快照库和release发布库
  3. debugInit.c tomcat启动错误
  4. 2021年春季学期-信号与系统-第六次作业参考答案
  5. nginx配置静态资源html,通过nginx服务器访问静态资源(示例代码)
  6. 使用函数计算三步实现深度学习 AI 推理在线服务
  7. 可实现自动设置尺寸的图片上传类
  8. 斜齿轮啮合 matlab,渐开线斜齿轮曲面精确建模及MatLab仿真
  9. jsp mysql 音乐网站_Maven+JSP+SSM+Mysql实现的音乐网站
  10. IOS开发之页面切换
  11. Ansible详解(十二)——Ansible Roles详解
  12. WCF分布式开发常见错误(17):无法启动MSMQ服务
  13. 程序员代码面试指南 IT名企算法与数据结构题目最优解
  14. 查询的端口 -解决端口被占用的问题
  15. avue框架中使用富文本编辑器
  16. frp穿透你的远程桌面
  17. TCL: an ANN-to-SNN Conversion with Trainable Clipping Layers
  18. Word2016中文字间距突然变大了是怎么回事?
  19. 云服务器搭建深度学习环境
  20. 如何让元素垂直居中?

热门文章

  1. 【T+】去掉畅捷通T+左边那些不用的云应用
  2. LIMS和TDM比较分析
  3. C# 求取圆心/球心坐标 ∈ C# 编程笔记
  4. Linux隔离网络,linux – 隔离网络上的单个NTP服务器
  5. 深入了解JVM之内存区域(一)
  6. java使用微信表情代码_iOS高仿微信表情输入功能代码分享
  7. 慧据价值 链接未来丨第八届数据技术嘉年华大会全议程呈现
  8. Ps笔刷:雨水掉落效果
  9. cesium使用primitives加载模型数据,点击事件
  10. java科技说明文范文800_说明文范文:生活因成功而精彩