头图

数据结构与算法经典题:农夫过河问题讲解

瞿小凯

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

看到这道题目,我们先缕清这几样东西(包括一个人)他们之间的关系。在这道题里,咱们只能两两组合。其中,有几个限制条件
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;



}
阅读 260

我是一个独立思考,喜欢纯粹的人,文科和专科是我曾经的身份牌,技术是我一直的理想。

46 声望
3 粉丝
0 条评论

我是一个独立思考,喜欢纯粹的人,文科和专科是我曾经的身份牌,技术是我一直的理想。

46 声望
3 粉丝
文章目录
宣传栏