lpj5203975 2022-11-30 00:02 采纳率: 100%
浏览 68
已结题

倒水问题的递归讨论部分

有三个杯子 A, B, C,容量分别为 V_A, V_B, V_C 。你可以执行若干次操作,在每次操作中:你可以选定两个杯子,将一个杯子中的水全部倒入另一个杯子中,如果两个杯子中水的总量超过了杯子的容量,那么 多余部分的水将会溢出 。

三个杯子中一开始分别有 a, b, c 的水,我想要知道能否使用不超过k 次操作,将三个杯子中的水量变成 a_0, b_0, c_0。如果可以则输出yes,否则输出no
C语言

知道要分六种情况来讨论递归,但不知道递归部分代码怎么写,想知道递归部分的思路操作

  • 写回答

1条回答 默认 最新

  • 於黾 2022-11-30 09:07
    关注

    1.只要是递归,一定要有一个终结条件,否则就会造成无限递归
    2.这个若干次操作,比如是n,需要传进来,每次递归的时候-1,到0的时候就结束
    3.一共有AB/AC/BA/BC/CA/CB,6种倒水的方式,这个方式编号1-6,也要作为参数传递进来,然后写个switch,根据不同方式进行操作
    4.具体操作过程就很简单了,比如A倒入B中,那么B+=A;A=0;再判断一下B是否超过最大值就行了
    5.如果某次操作后出现了需要的a_0, b_0, c_0就输出yes,同时把一个全局变量设置成true,表示找到了答案
    6.操作过后,执行6个递归函数,把6种排列都向下继续递归
    7.全部递归完成,如果全局变量依然是false,就输出no

    int V_A=10, V_B=8, V_C=5;
    int a_0=0, b_0=3, c_0=4;
    int a=10,b=2,c=3;
    int n=8;
    int find=0;
    
    void func(int n,int oper,int a,int b,int c)
    {
        if(n==0 || find)return;//如果已经达到次数就不要继续递归了,避免无限递归
        //这里也可以写如果状态和之前的某个状态一致就不继续递归了,这样n就可以不限制,但逻辑会比较复杂
        //你需要额外的结构体和链表来存这些状态
    //如果已经找到答案就不要继续递归了
        switch (oper)
        {
        case 1:        //A->B
            //这里只写1个举例,其它同理
            b+=a;
            a=0;
            if(b>V_B)b=V_B;
            break;
        case 2:        //A->C
            break;
        case 3:        //B->A
            break;
        case 4:        //B->C
            break;
        case 5:        //C->A
            break;
        case 6:        //C->B
            break;    
        default:
            break;
        }
        if(a==a_0 && b==b_0 && c==c_0)find=1;
        func(n-1,1,a,b,c);
        func(n-1,2,a,b,c);
        func(n-1,3,a,b,c);
        func(n-1,4,a,b,c);
        func(n-1,5,a,b,c);
        func(n-1,6,a,b,c);
    }
    
    
    int main()
    {
        func(n,0,a,b,c);//首次递归不进行任何操作,只为了能继续递归,这样可以节约代码,当然你也可以把1-6写在这里,写6行
    //这里abc一定要作为形参传递,不能用全局变量,否则每个分支的状态都一样了
        if(find)
        //打印
        else
        //打印
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 12月12日
  • 已采纳回答 12月4日
  • 创建了问题 11月30日

悬赏问题

  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥15 想问一下树莓派接上显示屏后出现如图所示画面,是什么问题导致的
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化