目录
题目:
示例:
分析:
代码:
题目:
示例:
分析:
题目比较长,我概括一下就是有一群怪物,每只怪物离城市的距离都不一样,并且靠近的速度也不一样,每次我们可以消灭一只,当怪物到达城市的时候我们就失败了,问我们最终可以消灭多少只怪物。
我的第一想法是直接模拟,不过做了一点小优化。我们每次都先将怪物的距离减去速度表示它们移动了,每次有到达城市的怪物(也就是距离城市小于等于0的)我们就记录下数量。最终我们比较一下到达城市的怪物和已经经过的轮数谁更大,这时候轮数就等于我们击杀的怪物数量,因为一轮只能杀一只怪物。如果达到城市的怪物数量大于我们击杀的数量,那么结束,我们返回击杀数即可。
我一开始觉得这么做应该勉强能过,因为对vector进行删除元素的操作很费时间,而这么操作不需要对数组进行删除元素的操作,虽然也是暴力模拟,但也不是单纯的模拟,不过结果还是超时了,我们就需要另外想一个办法。
我们先想想我们每轮需要击杀的怪物是哪一只,是离城市最近的吗?不是,就算一个怪物离城市很近,但是它的速度比较慢,那也是对我们暂时没有威胁的。
我们优先消灭的怪物是最快到达的怪物,所以我们可以把每个怪物到达城市所需花费的时间算出来,接着对花费时间从小到大升序排序,优先消灭靠前的怪物,不过我们并不需要知道具体是哪一只怪物,所以可以直接对存放花费时间的数组进行排序。
直接遍历排序后的数组,如果第 i 个元素小于等于 i ,那么就表示会有怪物在我们击杀它之前到达城市,这时候返回 i ,也就是轮数,同时也是等于我们击杀的怪物数量。
代码:
class Solution {
public:
int eliminateMaximum(vector<int>& dist, vector<int>& speed) {
//超时
int res=0;
while(res<dist.size()){
int num=0;
for(int i=0;i<dist.size();i++){
dist[i]-=speed[i]; //预先让怪物先移动
if(dist[i]<=0) num++; //如果怪物距离小于等于0则表示到达城市,记录数量
}
res++; //每轮至少可以击杀一个怪兽
if(num>res) break; //如果到达城市的怪物大于我们击杀的怪兽数,退出循环
}
return res;
int n=dist.size();
vector<int>cache(n);
for(int i=0;i<n;i++){ //提前计算出每只怪物到达城市需要多久
cache[i]=dist[i]/speed[i]+(dist[i]%speed[i]!=0);
}
//按照到达的先后顺序升序排序
sort(cache.begin(),cache.end());
for(int i=0;i<n;i++){
//如果有怪物达到的时间小于等于当前轮数,那么返回当前轮数
if(cache[i]<=i) return i;
}
return n;
}
};