给定两个最大容量分别为m和n升的水壶。水壶上没有标记,可以帮助我们测量较小的数量。任务是使用这两个水壶测量d升水。因此,我们的目标是从初始状态 (m, n) 到达最终状态 (0, d) 或 (d, 0)。
例子:
Input: 4 3 2
Output: (0, 0) –> (4, 0) –> (4, 3) –> (0, 3) –> (3, 0) –> (3, 3) –> (4, 2) –> (0, 2)
Input: 5 2 4
Output: (0, 0) –> (5, 0) –> (5, 2) –> (0, 2) –> (2, 0) –> (2, 2) –> (4, 0)
方法:使用 BFS 的方法已在上一篇文章中讨论过。在这篇文章中,讨论了一种使用记忆化和递归的方法。在任何时候,总共可以有六种可能性:
- 完全清空第一个水壶
- 完全清空第二个水壶
- 装满第一个水壶
- 装满第二个水壶
- 将第二个水壶中的水倒入第一个水壶中,直到第一个水壶已满或第二个水壶没有水为止
- 将第一个水壶中的水倒入第二个水壶中,直到第二个水壶已满或第一个水壶没有水为止
方法:使用递归,一一访问所有六种可能的移动,直到其中之一返回 True。由于可以重复相同的递归调用,因此每个返回值都使用记忆存储,以避免再次调用递归函数并返回存储的值。
下面是上述方法的实现:
# This function is used to initialize the
# dictionary elements with a default value.
from collections import defaultdict
# jug1 and jug2 contain the value
# for max capacity in respective jugs
# and aim is the amount of water to be measured.
jug1, jug2, aim = 4, 3, 2
# Initialize dictionary with
# default value as false.
visited = defaultdict(lambda: False)
# Recursive function which prints the
# intermediate steps to reach the final
# solution and return boolean value
# (True if solution is possible, otherwise False).
# amt1 and amt2 are the amount of water present
# in both jugs at a certain point of time.
def waterJugSolver(amt1, amt2):
# Checks for our goal and
# returns true if achieved.
if (amt1 == aim and amt2 == 0) or (amt2 == aim and amt1 == 0):
print(amt1, amt2)
return True
# Checks if we have already visited the
# combination or not. If not, then it proceeds further.
if visited[(amt1, amt2)] == False:
print(amt1, amt2)
# Changes the boolean value of
# the combination as it is visited.
visited[(amt1, amt2)] = True
# Check for all the 6 possibilities and
# see if a solution is found in any one of them.
return (waterJugSolver(0, amt2) or
waterJugSolver(amt1, 0) or
waterJugSolver(jug1, amt2) or
waterJugSolver(amt1, jug2) or
waterJugSolver(amt1 + min(amt2, (jug1-amt1)),
amt2 - min(amt2, (jug1-amt1))) or
waterJugSolver(amt1 - min(amt1, (jug2-amt2)),
amt2 + min(amt1, (jug2-amt2))))
# Return False if the combination is
# already visited to avoid repetition otherwise
# recursion will enter an infinite loop.
else:
return False
print("Steps: ")
# Call the function and pass the
# initial amount of water present in both jugs.
waterJugSolver(0, 0)
输出:
Steps:
0 0
4 0
4 3
0 3
3 0
3 3
4 2
0 2
时间复杂度:O(M * N)
辅助空间:O(M * N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。