青训营X豆包MarsCode技术训练营第六课之习题解析 | 豆包MarsCode AI刷题

29 阅读4分钟

小E的怪物挑战

这个问题的核心是根据游戏规则,模拟小E与怪物的战斗过程,找出她最多能够击败的怪物数目。具体来说,我们需要根据怪物的血量和攻击力来决定小E是否可以击败该怪物,并在击败每个怪物后更新小E的血量和攻击力,且击败的怪物必须遵循严格递增的顺序。

思路分析
  1. 首先的条件检查:小E初始的血量 H 和攻击力 A 需要满足击败某个怪物的条件。对于一个怪物,其血量必须小于小E的当前血量 H,攻击力必须小于小E的当前攻击力 A。
  2. 击败怪物的后效:每当小E击败一个怪物后,自己的血量和攻击力会增加,新的血量和攻击力会变为:new_H = H + hi new_A = A + ai,其中 ( hi ) 和 ( ai ) 分别是当前怪物的血量和攻击力。
  3. 序列限制:为了保证战斗节奏,后一个击败的怪物必须在血量和攻击力上都大于前一个怪物。即,击败的怪物顺序必须是严格递增的。
  4. 求解方式:这道题可以通过 贪心算法 来解决:
  • 先筛选出所有符合击败条件的怪物(血量和攻击力都小于当前的 H 和 A)。
  • 然后选择一个有效的击败顺序,使得每次选择的怪物都满足 "血量和攻击力都严格大于前一个怪物"。
解题步骤
  1. 筛选有效怪物:将所有怪物按照血量和攻击力排序,方便之后选择。
  2. 动态更新小E的状态:逐步模拟击败怪物的过程。每次选择当前符合条件且血量、攻击力都严格大于前一个怪物的怪物。
  3. 输出最大击败的怪物数。
Python 实现
def max_monsters(n, H, A, h, a):
    # 创建怪物列表,包含每个怪物的血量和攻击力
    monsters = [(h[i], a[i]) for i in range(n)]
    # 先按照怪物的血量和攻击力进行排序(血量优先,攻击力次之)
    monsters.sort()

    # 初始化击败的怪物数量
    defeated_count = 0

    # 初始血量和攻击力
    current_H = H
    current_A = A

    for monster in monsters:
        # 如果当前怪物可以击败(血量和攻击力都小于当前状态)
        if monster[0] < current_H and monster[1] < current_A:
            # 击败怪物后,更新小E的血量和攻击力
            current_H += monster[0]
            current_A += monster[1]
            # 增加击败的怪物数量
            defeated_count += 1

    return defeated_count
测试样例

n = 3 H = 4 A = 5 h = [1, 2, 3] a = [3, 2, 1]

print(max_monsters(n, H, A, h, a)) # 输出:1

解释
  1. 怪物排序:我们首先对怪物按血量和攻击力排序,使得小E每次选择一个怪物时,后一个怪物的血量和攻击力都严格大于前一个怪物,这样可以满足题目中的递增要求。
  2. 遍历怪物:遍历排序后的怪物列表,对于每个怪物,如果它的血量和攻击力都小于当前小E的血量和攻击力,那么小E可以击败它,并更新小E的血量和攻击力。
  3. 最终结果:返回击败的最大怪物数量。

时间复杂度

  • 排序操作的时间复杂度是 ( O(n \log n) ),其中 ( n ) 是怪物的数量。
  • 遍历怪物进行状态更新的时间复杂度是 ( O(n) )。

所以,整体时间复杂度是 ( O(n \log n) ),这是一个高效的解法。

测试样例:

输入: n = 3, H = 4, A = 5 h = [1, 2, 3] a = [3, 2, 1] 输出:1

解释:

  • 小E可以击败血量为 1 且攻击力为 3 的怪物,击败后小E的血量和攻击力更新为 5 和 8。
  • 但是接下来的怪物都无法击败,因为它们的血量和攻击力都不小于小E的当前属性,因此最大击败怪物数为 1。

这个解法通过合理的排序和遍历有效地解决了问题。