GYM 100247 F. Battle Fury(二分)

来源:互联网 发布:商品标签软件打印机 编辑:程序博客网 时间:2024/05/23 19:19

Description
n只怪兽,第i只怪兽有a[i]血,每次选中一个怪兽攻击可以对其造成p点伤害,对其余怪兽每只造成q点溅射伤害,问最少需要多少次攻击可以打死所有怪兽
Input
第一行三个整数n,p,q分别表示怪兽数量,攻击伤害和溅射伤害,之后n个整数a[i]表示每只怪兽的血量
(1<=n<=200000,1<=q<=p<=1e9,1<=a[i]<=1e9)
Output
输出杀死所有怪兽的最少攻击次数
Sample Input
2 3 2
5 5
Sample Output
2
Solution
二分答案,对于一个二分值k,如果某只怪兽的剩余血量不大于k*q,那么这只怪兽不需要多余攻击直接被溅射死,否则需要攻击(a[i]-k*q)/p+((a[i]-k*q)%p==0?0:1)次,看所有怪兽需要的攻击次数与k的大小关系决定二分方向
Code

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>#include<set>#include<ctime>using namespace std;typedef long long ll;#define INF 0x3f3f3f3f#define maxn 222222int n;ll p,q,a[maxn];bool check(ll k){    ll ans=0;    for(int i=1;i<=n;i++)    {        if(a[i]<=k*q)continue;        else ans+=(a[i]-k*q)/p+((a[i]-k*q)%p==0?0:1);    }    if(ans<=k)return 1;    return 0;}int main(){    while(~scanf("%d%I64d%I64d",&n,&p,&q))    {        ll Max=0;        for(int i=1;i<=n;i++)        {            scanf("%I64d",&a[i]);            Max=max(Max,a[i]);        }        if(p==q)        {            printf("%I64d\n",Max/p+(Max%p==0?0:1));            continue;        }        p-=q;        ll l=1,r=Max,mid,ans=r;        while(l<=r)        {            mid=(l+r)/2;            if(check(mid))r=mid-1,ans=mid;            else l=mid+1;        }        printf("%I64d\n",ans);    }    return 0;}
0 0
原创粉丝点击