atcoder Silver Fox vs Monster (贪心 一维差分)

题目大意:

现在有n个怪物,第i个怪物有血量Hi,现在我们可以使用AOE攻击,使得放AOE的中心范围内2*X长度的怪物血量减少A. 问我们最少需要多少次AOE攻击。

AOE攻击示例:

解题思路:

首先,我们想到做一些预处理,包括把每个怪物的血量理解为需要多少次攻击,然后让这些怪物按照坐标从小到大排序。这时候我们就可以贪心了,已知要处理的怪物位置为pos,而且血量大于0,那么让这只怪物承受的攻击范围是左端点,这样可以尽可能地让右边的怪物受到攻击 即: 一段攻击的距离为[pos,pos+2x ] 对于处在pos位置的需要攻击的怪物。然后我们需要用到二分查找pos+2x 的怪物,完成区间减的操作,区间减需要用到差分。

#include <bits/stdc++.h>
#define int long long 
using namespace std;
int32_t main(){
    int n,d,a;cin>>n>>d>>a;
    vector<pair<int,int>> arrmv;
    for(int i=0;i<n;i++){
        int x,y;cin>>x>>y;
        arrmv.push_back({x,(int)ceil((double)y/(double)a)});
    }
    sort(arrmv.begin(),arrmv.end());
    vector<int> dif(arrmv.size()+1,0);
    int ans=0;
    vector<int> sha;
    for(int i=0;i<(int)arrmv.size();i++)sha.push_back(arrmv[i].first);
    for(int i=0;i<(int)arrmv.size();i++){
        if(i)dif[i]+=dif[i-1];
        arrmv[i].second+=dif[i];
        if(arrmv[i].second<=0)continue;
        else{
            ans+=arrmv[i].second;
            int lpos=upper_bound(sha.begin(),sha.end(),arrmv[i].first+2*d)-sha.begin();
            dif[i]-=arrmv[i].second;
            dif[lpos]+=arrmv[i].second; 
        }
    }
    cout<<ans<<endl;
	return 0;
}
发布了171 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/FrostMonarch/article/details/104099286
Fox