题意:
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); } }