破冰行动问题
问题描述
小C发明了一款破冰游戏,在河面上有n块冰块,编号从1到n,企鹅站在某块冰块上,编号为K(用-1表示企鹅所在的冰块)。目标是通过破坏一些冰块,使企鹅掉落到河中。破坏冰块时需要根据冰块的强度进行操作,冰块两侧一旦没有与河岸连接,冰块就会掉落到河中。
每个冰块都有不同的强度,表示需要的力量。为了使企鹅掉落到河中,必须破坏掉其两侧的冰块(即不能破坏企鹅所在的冰块)。目标是计算使企鹅掉落所需要的最小总力量。
例如,当冰块的强度且企鹅位于冰块时,破坏冰块1和冰块4分别需要力量7和2,总力量为9。
解题思路
- 定位企鹅的位置:找到企鹅所在的冰块位置。
- 分离两侧的冰块:将企鹅所在冰块的左侧和右侧的冰块分别存储在两个列表中。
- 计算最小力量:分别找到左侧和右侧冰块中强度最小的冰块,并计算它们的强度之和。
代码实现
定位企鹅的位置+分离两侧的冰块
这两个步骤都需要用到for循环遍历整个冰块列表A,并对每个冰块的数据进行分析、操作。由于在同一个函数中分别写两个可迭代对象完全相同的for循环,会导致整段代码过于繁琐,所以这两个步骤就合到一起讨论了。
两个步骤的具体实现方法分别如下:
- 定位企鹅的位置:遍历冰块列表,找到企鹅所在的位置。
- 分离两侧的冰块:将企鹅左侧的冰块强度存储在一个列表中,将右侧的冰块强度存储在另一个列表中。
在这里定义两个列表left和right,分别用于存储企鹅所在冰块左侧和右侧的冰块强度;定义标志变量flag,假设flag为0时,冰块强度添加到left列表中,反之冰块强度添加到right列表中。
需要注意的是,原列表A中冰块强度表示为-1的冰块是企鹅所在的冰块,作为left和right的分界点出现,不能被看作该冰块的强度并添加到left或right列表中。
具体代码如下:
left = []
right = []
flag = 0
for i in range(n):
if A[i] == -1:
flag = 1
continue
if flag == 0:
left.append(A[i])
else:
right.append(A[i])
计算最小力量
分别找到left和right两个列表中的最小值,并计算它们的和。此步骤使用min()函数分别求两个列表中的最小值即可。具体代码如下:
min_left = min(left)
min_right = min(right)
return min_left + min_right
完整代码
def solution(n: int, A: list) -> int:
left = []
right = []
flag = 0
for i in range(n):
if A[i] == -1:
flag = 1
continue
if flag == 0:
left.append(A[i])
else:
right.append(A[i])
min_left = min(left)
min_right = min(right)
return min_left + min_right
if __name__ == '__main__':
print(solution(5, [7, -1, 6, 2, 5]) == 9)
print(solution(6, [4, -1, 3, 1, 8, 10]) == 5)
print(solution(7, [9, 5, -1, 4, 6, 7, 2]) == 7)