有三个杯子 A, B, C,容量分别为 V_A, V_B, V_C 。你可以执行若干次操作,在每次操作中:你可以选定两个杯子,将一个杯子中的水全部倒入另一个杯子中,如果两个杯子中水的总量超过了杯子的容量,那么 多余部分的水将会溢出 。
三个杯子中一开始分别有 a, b, c 的水,我想要知道能否使用不超过k 次操作,将三个杯子中的水量变成 a_0, b_0, c_0。如果可以则输出yes,否则输出no
C语言
知道要分六种情况来讨论递归,但不知道递归部分代码怎么写,想知道递归部分的思路操作
有三个杯子 A, B, C,容量分别为 V_A, V_B, V_C 。你可以执行若干次操作,在每次操作中:你可以选定两个杯子,将一个杯子中的水全部倒入另一个杯子中,如果两个杯子中水的总量超过了杯子的容量,那么 多余部分的水将会溢出 。
三个杯子中一开始分别有 a, b, c 的水,我想要知道能否使用不超过k 次操作,将三个杯子中的水量变成 a_0, b_0, c_0。如果可以则输出yes,否则输出no
C语言
知道要分六种情况来讨论递归,但不知道递归部分代码怎么写,想知道递归部分的思路操作
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
//打印
}