之前因为这题困扰很久,虽然知道是要算攻占比,但是一直不懂为什么,看了优秀代码的评优报告,突然觉得自己很傻逼
现在把大神的思路贴上来,其实是很简单的数学问题。。
首先假设有两个敌人(a1,b1) (a2,b2)
如果选择先攻击第一个敌人,再攻击第二个敌人
血量为:[(a1+a2)b1-a1]+[a2b2-a2]=a1b1+a2b1+a2b2-(a1+a2)
如果选择先攻击第二个敌人,再攻击第一个敌人
血量为:[(a1+a2)b2-a2]+(a1b1-a1)=a1b1+a1b2+a2b2-(a1+a2)
显两种方案的差别在于a2b1和a1b2,若选择第一种方案,则a2b1<a1b2,即a1/b1>a2/b2。若选择第二种方案,则a1/b1<a2/b2
即a/b的值越大,排在越前面。
另外这道题我也碰到两个问题
1.血量的值可能超int,所以要用__int64(很多人都死在这上面)
2.就是排序的函数使用,之前我自己做的时候用的是qsort,结果一直WA,改用sort就AC。(之后会附上关于这两个函数的转载blog)
贴代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct enemy
{
int a;
int b;
double aver;
__int64 total;
}s[100010];
bool cmp(enemy x,enemy y)
{
return x.aver>y.aver;
}
int main()
{
int n,i;
__int64 sum=0;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d%d",&s[i].a,&s[i].b);
s[i].aver=(s[i].a*1.0)/(s[i].b*1.0);
}
sort(s,s+n,cmp);
for(i=0;i<n;i++)
{
if(i>=1)
s[i].total=s[i-1].total+s[i].a;
else
s[i].total=s[i].a;
}
for(i=0;i<n;i++)
{
sum=(sum+s[i].a*(s[i].b-1)+s[i].b*(s[n-1].total-s[i].total))%1000000007;
}
printf("%I64d\n",sum);
return 0;
}