1921. 消灭怪物的最大数量

【算法题解】保护城市:怪物消灭最大数量问题详解

题目描述

你正在玩一款电子游戏,目标是保护城市不被怪物侵袭。

游戏设定如下:

  • n 个怪物,第 i 个怪物与城市的初始距离是 dist[i](单位:千米)。
  • 每个怪物以恒定速度向城市前进,速度为 speed[i](单位:千米/分钟)。
  • 武器在游戏开始时是充满电的,可以立即消灭一个怪物,但之后每次消灭怪物后需要 1 分钟充电。
  • 怪物从第 0 分钟开始移动。
  • 如果在任意一分钟的开始时,任何怪物恰好到达城市(距离为0),游戏立即失败。
  • 目标是计算在游戏失败前,最多能消灭多少怪物。

问题理解与分析

关键在于怪物的到达时间和你的攻击节奏:

  • 怪物到达时间计算:第 i 个怪物的到达时间是 ceil(dist[i] / speed[i]) 分钟。
  • 攻击时间线:你从第 0 分钟开始,每分钟可以消灭一个怪物(武器开始时已充满电,消灭第一个怪物无需等待)。
  • 胜利条件:在第 k 分钟消灭第 k 个怪物之前,该怪物必须还未抵达城市,即 time[k] > k
  • 一旦有怪物的到达时间小于等于它应该被消灭的时间,意味着该怪物已到达城市,游戏失败。

解题思路

计算所有怪物到达城市的时间:

对每个怪物,计算它到达城市的时间(分钟数):

  1. t i m e [ i ] = ⌈ d i s t [ i ] s p e e d [ i ] ⌉ time[i] = \lceil \frac{dist[i]}{speed[i]} \rceil time[i]=speed[i]dist[i]
  2. 排序怪物按到达时间升序:

先消灭那些最快到达的怪物。

  1. 逐个判断是否可以按时消灭:

遍历排序后的时间数组,如果在第 i 分钟,第 i 个怪物的到达时间 time[i] 小于或等于 i,则游戏失败。

  1. 统计能消灭的怪物数量:

返回满足条件的最大索引 i


代码实现

import math
from typing import List

class Solution:
    def eliminateMaximum(self, dist: List[int], speed: List[int]) -> int:
        # 计算所有怪物到达时间
        time = [math.ceil(d / s) for d, s in zip(dist, speed)]
        # 按到达时间升序排序
        time.sort()
        
        # 遍历判断是否可以按时消灭
        for i, t in enumerate(time):
            if t <= i:
                return i  # 不能消灭第 i 个怪物,返回前面消灭的数量
        return len(dist)  # 所有怪物都能消灭

时间与空间复杂度分析

  • 时间复杂度:排序时间是 O(n log n),计算时间是 O(n),整体为 O(n log n)。
  • 空间复杂度:存储时间数组需要 O(n) 额外空间。

这已经是最优的解决方案,因为必须排序怪物到达时间。


示例说明

示例 1

dist = [1, 3, 4]
speed = [1, 1, 1]
输出:3

过程说明

  • 到达时间分别为 [1, 3, 4] 分钟。
  • 按顺序消灭:
    • 第 0 分钟消灭距离1的怪物
    • 第 1 分钟消灭距离3的怪物(剩余距离2)
    • 第 2 分钟充电,怪物还没到达
    • 第 3 分钟消灭距离4的怪物(剩余距离1)
  • 所有怪物都可以被消灭,返回 3。

示例 2

dist = [1, 1, 2, 3]
speed = [1, 1, 1, 1]
输出:1

过程说明

  • 到达时间为 [1, 1, 2, 3]
  • 按时间排序仍是 [1, 1, 2, 3]
  • 第 0 分钟消灭第一个怪物
  • 第 1 分钟时第二个怪物距离0,游戏失败
  • 只能消灭 1 个怪物。

示例 3

dist = [3, 2, 4]
speed = [5, 3, 2]
输出:1

过程说明

  • 计算到达时间:
    • 怪物0: ceil(3/5) = 1
    • 怪物1: ceil(2/3) = 1
    • 怪物2: ceil(4/2) = 2
  • 排序到达时间为 [1, 1, 2]
  • 第 0 分钟消灭第一个怪物(到达时间1)
  • 第 1 分钟时,第二个怪物距离0,游戏失败
  • 只能消灭 1 个怪物。

总结

这道题用一个很经典的“贪心排序”思路:

  • 先算出怪物到达时间
  • 按时间顺序消灭怪物
  • 在消灭顺序上检测是否怪物已经到达城市

只要在每一步判断条件满足即可,简单明了且效率高。

如果你在游戏设计或类似的场景中需要处理“有限资源按顺序处理多事件”的问题,这种思路非常有参考价值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值