leetcode 365. Water and Jug Problem

本文探讨了给定两个容量不同的水罐如何准确测量特定水量的问题。通过数学方法验证了解的存在性,并提供了一个简洁的C++实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

365 Water and Jug Problem

You are given two jugs with capacities x and y litres. There is an infinite amount of water supply available. You need to determine whether it is possible to measure exactly z litres using these two jugs.

If z liters of water is measurable, you must have z liters of water contained within one or both buckets by the end.

Operations allowed:

  • Fill any of the jugs completely with water.
  • Empty any of the jugs.
  • Pour water from one jug into another till the other jug is completely full or the first jug itself is empty.

Example 1: (From the famous "Die Hard" example)

Input: x = 3, y = 5, z = 4
Output: True

Example 2:

Input: x = 2, y = 6, z = 5
Output: False

有一个容量为3升和一个容量为5升的水罐,问我们如何准确的称出4升的水。我想很多人都知道怎么做,先把5升水罐装满水,倒到3升水罐里,这时5升水罐里还有2升水,然后把3升水罐里的水都倒掉,把5升水罐中的2升水倒入3升水罐中,这时候把5升水罐解满,然后往此时有2升水的3升水罐里倒水,这样5升水罐倒出1升后还剩4升即为所求。这个很多人都知道,但是这道题随意给我们了三个参数,问有没有解法,这就比较难了。这里我就照搬网上大神的讲解吧:

这道问题其实可以转换为有一个很大的容器,我们有两个杯子,容量分别为x和y,问我们通过用两个杯子往里倒水,和往出舀水,问能不能使容器中的水刚好为z升。那么我们可以用一个公式来表达:

z = m * x + n * y

其中m,n为舀水和倒水的次数,正数表示往里舀水,负数表示往外倒水,那么题目中的例子可以写成: 4 = (-2) * 3 + 2 * 5,即3升的水罐往外倒了两次水,5升水罐往里舀了两次水。那么问题就变成了对于任意给定的x,y,z,存不存在m和n使得上面的等式成立。

根据裴蜀定理,ax + by = d的解为 d = gcd(x, y),那么我们只要只要z % d == 0,上面的等式就有解,所以问题就迎刃而解了,我们只要看z是不是x和y的最大公约数的倍数就行了,别忘了还有个限制条件x + y >= z,因为x和y不可能称出比它们之和还多的水。


注意:求最大公约数的代码

    int gcd(int x, int y)   //求最大公约数
    {
        if (y == 0) return x;
        return gcd(y, x % y);
    }


class Solution {
public:
    bool canMeasureWater(int x, int y, int z) 
    {
        return z == 0 || (x + y >= z && z % gcd(x, y) == 0);    
    }
    
    int gcd(int x, int y)   //求最大公约数
    {
        if (y == 0) return x;
        return gcd(y, x % y);
    }
};

参考:https://www.cnblogs.com/grandyang/p/5628836.html



内容概要:文章详细介绍了ETL工程师这一职业,解释了ETL(Extract-Transform-Load)的概念及其在数据处理中的重要性。ETL工程师负责将分散、不统一的数据整合为有价值的信息,支持企业的决策分析。日常工作包括数据整合、存储管理、挖掘设计支持和多维分析展现。文中强调了ETL工程师所需的核心技能,如数据库知识、ETL工具使用、编程能力、业务理解能力和问题解决能力。此外,还盘点了常见的ETL工具,包括开源工具如Kettle、XXL-JOB、Oozie、Azkaban和海豚调度,以及企业级工具如TASKCTL和Moia Comtrol。最后,文章探讨了ETL工程师的职业发展路径,从初级到高级的技术晋,以及向大数据工程师或数据产品经理的横向发展,并提供了学习资源和求职技巧。 适合人群:对数据处理感兴趣,尤其是希望从事数据工程领域的人士,如数据分析师、数据科学家、软件工程师等。 使用场景及目标:①了解ETL工程师的职责和技能要求;②选择适合自己的ETL工具;③规划ETL工程师的职业发展路径;④获取相关的学习资源和求职建议。 其他说明:随着大数据技术的发展和企业数字化转型的加速,ETL工程师的需求不断增加,尤其是在金融、零售、制造、人工智能、物联网和区块链等领域。数据隐私保护法规的完善也使得ETL工程师在数据安全和合规处理方面的作用更加重要。
### Python 数据结构练习题及相关解析 以下是针对 Python 版数据结构的一些经典练习题目及其解析: #### 1. 扩展 `buildParseTree` 方法以支持无空格的数字表达式 此问题来源于编程练习,目标是对现有函数进行改进以便于处理更复杂的输入形式。可以通过正则表达式或其他字符串分割技术实现这一功能。 ```python import re def buildParseTree(fpexp): fplist = [] temp_str = "" for char in fpexp: if char.isdigit(): temp_str += char elif temp_str: fplist.append(temp_str) temp_str = "" if char in "+-*/()": fplist.append(char) if temp_str: fplist.append(temp_str) pStack = [] eTree = [""] # 假设树结构为列表表示法 pStack.append(eTree) currentTree = eTree for i in fplist: if i == '(': currentTree.append([""]) pStack.append(currentTree) currentTree = currentTree[-1] elif i not in ['+', '-', '*', '/', ')']: currentTree.append(int(i)) elif i in ['+', '-', '*', '/']: currentTree.append(i) elif i == ')': currentTree = pStack.pop() return eTree[:-1] print(buildParseTree("(3+5)*(7-2)")) # 输出应展示树形结构 ``` 上述代码通过遍历字符串并构建相应的解析树完成任务[^2]。 --- #### 2. 实现比较含退格符的字符串 该问题是 LeetCode 上的经典题目之一,涉及栈的应用场景。具体逻辑已在引用中描述清楚。 ```python class Solution: def backspaceCompare(self, s: str, t: str) -> bool: def process_stack(word): stack = [] for c in word: if c != '#': stack.append(c) elif stack: stack.pop() return ''.join(stack) return process_stack(s) == process_stack(t) solution = Solution() result = solution.backspaceCompare("xy#z", "xw#wz") # True print(result) ``` 这段代码实现了基于栈的操作来模拟退格行为,并最终对比两串的结果是否一致[^3]。 --- #### 3. 使用递归绘制科赫雪花曲线 这是一个经典的分形几何图形生成案例,利用了递归来定义复杂图案的构成方式。 ```python from turtle import * def koch(size, n): if n == 0: forward(size) else: for angle in [0, 60, -120, 60]: left(angle) koch(size / 3, n - 1) def main(level=4, length=300): setup(800, 800) speed(0) penup(); goto(-length / 2, length / 3); pendown() for _ in range(3): koch(length, level) right(120) if __name__ == "__main__": main() done() ``` 以上脚本展示了如何借助海龟绘图模块创建视觉化的分形效果[^4]。 --- #### 4. 双坛子倒水问题求解 这是典型的广度优先搜索 (BFS) 或状态空间探索类问题实例化版本。 ```python from collections import deque def water_jug_problem(capacity_a, capacity_b, target): visited = set() queue = deque([(0, 0)]) while queue: a, b = queue.popleft() if (a, b) in visited: continue visited.add((a, b)) if a == target or b == target: print(f"Solution found with {a} gallons and {b} gallons.") break actions = [ ("Fill A", min(capacity_a, a), b), ("Fill B", a, min(capacity_b, b)), ("Empty A", max(a - capacity_a, 0), b), ("Empty B", a, max(b - capacity_b, 0)), ("Pour A to B", max(0, a - (capacity_b - b)), min(capacity_b, b + a)), ("Pour B to A", min(capacity_a, a + b), max(0, b - (capacity_a - a))) ] for action_name, next_a, next_b in actions: if (next_a, next_b) not in visited: queue.append(((next_a, next_b))) water_jug_problem(4, 3, 2) ``` 这个解决方案采用 BFS 来穷尽所有可能的状态转移路径直到找到满足条件的目标状态为止。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值