破冰行动问题 | 豆包MarsCode AI刷题

137 阅读3分钟

破冰行动问题

问题描述

小C发明了一款破冰游戏,在河面上有n块冰块,编号从1到n,企鹅站在某块冰块上,编号为K(用-1表示企鹅所在的冰块)。目标是通过破坏一些冰块,使企鹅掉落到河中。破坏冰块时需要根据冰块的强度进行操作,冰块两侧一旦没有与河岸连接,冰块就会掉落到河中。

每个冰块都有不同的强度AiA_i,表示需要的力量。为了使企鹅掉落到河中,必须破坏掉其两侧的冰块(即不能破坏企鹅所在的冰块)。目标是计算使企鹅掉落所需要的最小总力量。

例如,当冰块的强度A=[7,1,6,2,5]A=[7,−1,6,2,5]且企鹅位于冰块K=2K=2时,破坏冰块1和冰块4分别需要力量7和2,总力量为9。

解题思路

  1. 定位企鹅的位置:找到企鹅所在的冰块位置。
  2. 分离两侧的冰块:将企鹅所在冰块的左侧和右侧的冰块分别存储在两个列表中。
  3. 计算最小力量:分别找到左侧和右侧冰块中强度最小的冰块,并计算它们的强度之和。

代码实现

定位企鹅的位置+分离两侧的冰块

这两个步骤都需要用到for循环遍历整个冰块列表A,并对每个冰块的数据进行分析、操作。由于在同一个函数中分别写两个可迭代对象完全相同的for循环,会导致整段代码过于繁琐,所以这两个步骤就合到一起讨论了。

两个步骤的具体实现方法分别如下:

  • 定位企鹅的位置:遍历冰块列表,找到企鹅所在的位置。
  • 分离两侧的冰块:将企鹅左侧的冰块强度存储在一个列表中,将右侧的冰块强度存储在另一个列表中。

在这里定义两个列表leftright,分别用于存储企鹅所在冰块左侧和右侧的冰块强度;定义标志变量flag,假设flag0时,冰块强度添加到left列表中,反之冰块强度添加到right列表中。

需要注意的是,原列表A中冰块强度表示为-1的冰块是企鹅所在的冰块,作为leftright的分界点出现,不能被看作该冰块的强度并添加到leftright列表中。

具体代码如下:

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])

计算最小力量

分别找到leftright两个列表中的最小值,并计算它们的和。此步骤使用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)