题目:
一个农夫在河边带了一只狼、一只羊和一颗白菜,他需要把这三样东西用船带到河的对岸。然而,这艘船只能容下农夫本人和另外一样东西。如果农夫不在场的话,狼会吃掉羊,羊也会吃掉白菜。请编程为农夫解决这个过河问题。
思路:
看到这道题目,我们先缕清这几样东西(包括一个人)他们之间的关系。在这道题里,咱们只能两两组合。其中,有几个限制条件
1.狼不能和羊在一起
2.羊不能和白菜在一起
(这两个条件也会成为我们之后算法里逻辑做限制的一部分)
命名相关变量
现在,我们对它们进行命名,我们先用数字表示这些东西(和人)
0——狼、1——羊、2——白菜、3——农夫
(记得一定是从0开始标记哦)
接下来,我们就是标记河的两岸,我们给河的两岸分别表示为东岸和西岸(当然北岸和南岸也行,随意啦)。以此证明他们到达,为了让咱们的计算机能够看懂,我们表示为
0——起始河岸
1——到达的河岸
如果狼到达了对岸,我们用数组就可以表示为aStep 1,其他同理。
(这里的a数组表示存储每一步中各个对象所处的位置,除此之外,我们还需要数组b[N]来存储每一步中农夫是如何过河的)
因此,完整代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 15
int a[N][4];
int b[N];
char* name[] =
{
" ",
"and wolf",
"and goat",
"and cabbage"
};
int search(int step)
{
int i;
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 < Step)
printf(" the %d time\n", i + 1);
if (i > 0 && i < Step)
{
if (a[i][3] == 0) /*农夫在本岸*/
{
printf(" -----> farmer ");
printf("%s\n", name[b[i] + 1]);
}
else /*农夫在对岸*/
{
printf(" <----- farmer ");
printf("%s\n", name[b[i] + 1]);
}
}
}
printf("\n\n\n\n");
return 0;
}
for (i = 0; i < Step; 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;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。