题意:
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);
}
}
京公网安备 11010502036488号