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

本文介绍了一种解决特定问题的算法,该问题涉及计算最少需要多少次AOE攻击来击败一系列按坐标排序的怪物。通过预处理怪物血量、贪心策略及二分查找与差分技巧,实现了高效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:

现在有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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值