三个水杯倒水问题

三个水杯倒水问题问题描述:有3个水杯,水杯的容量为a,b,c升,a,b,c为正数,水杯可以从水源处接满水或将水倒入水源,也可以将杯子中的水倒入其他杯中,请问可以量出多少种体积的水,并列出。(注:量出的水必须再某一个杯中)解答错误想法一开始,我想着用数学方法处理它,把倒水分为两种,一种是将满杯的水倒入另一杯中,如果另一个杯是空的,当前杯中的水相当于做减法,另一种是另一杯子是有水的,那么就相...
摘要由CSDN通过智能技术生成

三个水杯倒水问题

问题描述:

有3个水杯,水杯的容量为a,b,c升,a,b,c为正数,水杯可以从水源处接满水或将水倒入水源,也可以将杯子中的水倒入其他杯中,请问可以量出多少种体积的水,并列出。(注:量出的水必须在某一个杯中)

解答

错误想法

一开始,我想着用数学方法处理它,把倒水分为两种,一种是将满杯的水倒入另一杯中,如果另一个杯是空的,当前杯中的水相当于做减法,另一种是另一杯子是有水的,那么就相当于给另一杯中的水做加法。然后呢,我就想枚举出所有加法和减法的可能,很显然,这种方法会遗漏一些情况,因为从一杯水往另一个杯子倒水,两个杯子都有可能处于非空但是非满杯的情况。

然后呢,我想了很久。

正确的枚举倒水操作

我重新思考这个问题,想一想每次倒水的或者清空杯子的操作是有限的:

  1. 给a杯充满水,给b杯充满水,给c杯充满水三种操作;
  2. 如果a杯非空清空a杯,如果b杯非空清空b杯,如果c杯非空情况c杯三种操作;
  3. 如果a杯非空将a杯中的水倒入b杯中,或者将a杯中的水倒入c杯中,同理b杯非空、c杯非空共6中可能的操作。

这样,每一次最多可以有12种操作的可能,可以想象存在一个无限容量的杯子,这12种操作就可以理解成a,b,c三个杯子加无限容量杯子共四个杯子两两之间的倒入倒出操作(4*3)。

终止条件

每一步的倒出操作可以枚举,但是呢,这个操作可以无限进行下去,我们必须找到一个可以让程序终止的条件。

我们假设当前杯子中水的体积为(x, y, z)作为状态,每次操作,状态(x,y,z)都会转移到另一个状态,如果这个状态在之前已经被处理过了,那么就不在处理这个状态。

如果我们把每一个状态都看成图中的一个顶点,那么终止条件就是所有可能的状态都被访问了。

所以我们可以用图的遍历程序解决问题。

广度优先遍历

我们为了表达每次取出每一次水的操作步骤最少,我们用广度优先遍历。

时间复杂度

O(abc),总共最多有(a+1)(b+1)(c+1)种可能的状态,产生每一个状态需要倒水一次。

空间复杂度

O(abc), 保存已处理的状态需要一个哈希表,总共最多有(a+1)(b+1)(c+1)种可能的状态。

编码

from collections import deque

def bfs(volumns=(3, 5, 7), state=(0, 0, 0), visited=set(), task=[], actions=[], ans={
   }):
    visited.add(tuple(state))
    for idx, cur_vol in enumerate(state):
        if cur_vol not in ans:
            ans[cur_vol] = 
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值