题意:

n个怪兽,各自的攻击力atk和生命值hp给出,让英雄去杀死所有的怪物
规则:英雄对于一个怪物,伤害等于攻击次数,英雄在攻击怪物前先受到怪物攻击,伤害为所有怪物的攻击力,回合制进行,问英雄杀死所有怪物最少受到多少伤害?

题解:

其实很简单,我们只需要按照性价比排序,将攻击强命脆的怪物先攻击即可
但要注意,怪物的生命值并非它能承受的攻击次数,所以我们将生命转化成所能承受的攻击次数
可以用公式a[i].time=ceil((-1+sqrt(1+8.0*a[i].hp))/2.0);
竟然一元二次方程求解
但。。。我用的二分(我快炸了),然后。。。wa了一晚上
图片说明
第二题我用对拍都没发现什么错误,
最后将二分换成公式就a了
但是还是没发现二分哪错了。。。
图片说明

代码:

这是我写的代码,目前是wa的
注释部分为公式,用公式是对的

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
inline int read(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
   return s*w;
}
const int maxn=1e5+9;
struct node
{
    int hp;//生命值 
    int atk;//攻击力 
    double val;
    int time;
}a[maxn];
bool cmp(node a,node b)
{
    return a.val>b.val;
}
bool check(int x,int i)
{
    if(x*(x+1)/2>=a[i].hp)return 1;
    return 0; 
}
int main()
{
    int t;
    cin>>t;
    for(int ii=1;ii<=t;ii++)
    {
        int n;
        cin>>n;
        ll sum=0;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i].hp>>a[i].atk;
            //
            sum+=a[i].atk;
            int l=0,r=a[i].hp;
            while(l<r)
            {
                int mid=l+r>>1;
                if(check(mid,i))r=mid;
                else l=mid+1;
            }
            a[i].time=l;
        //    a[i].time=ceil((-1+sqrt(1+8.0*a[i].hp))/2.0);;
            a[i].val=(double)a[i].atk/(double)a[i].time;
        }
         sort(a+1,a+1+n,cmp);
         ll ans=0;
        for(int i=1;i<=n;i++)
        {
    //        ans+=sum;
            ll x=a[i].time;
            ans+=sum*x;
            sum-=a[i].atk;
        }
        printf("Case #%d: %lld\n",ii,ans);
    }

}