Kiil the monster(性价比问题

# 题意
n个怪兽,每个怪兽有hp血量和atk攻击值,每一秒英雄都会受到所有存活怪兽的攻击,英雄攻击每个怪兽的伤害等于攻击当前怪兽的次数,第一次攻击第i个怪兽的伤害为1,第二次为2,计算英雄杀光所有怪兽后承受的最小攻击
数据范围:
T:1e3
n:(1,1e5)
所有测试数据的n的和<1e6
Hp,atk [ 1 , 1e5 ]

# 题解   
总体思想:先搞死伤害高的
n个怪兽每个怪兽最大都是1e5,总和会爆int,使用long long
将每个怪兽的存活时间计算出,计算出它的平均伤害
按照平均伤害为第一关键字,攻击值为第二关键字从大到小排序
比值排序有精度误差 ,可以改成这样: a/b > c/d= a*d > b*c 

 1 #pragma GCC optimize(3,"Ofast","inline")
 2 #include <bits/stdc++.h>
 3 #define LL long long
 4 using namespace std;
 5 const int N=1e5+10;
 6 struct monster{
 7     LL hp;
 8     LL atk;
 9     LL alive;//预处理所有怪兽从被攻击开始能够存活的时间
10     double average;//存活时间内的平均攻击
11 }mon[N];
12 inline LL Alive(LL x){
13     LL tim,res=0;
14     for (int i = 1;; ++i){
15         res+=i;
16         if(res>=x){
17             tim=i;
18             break;
19         }
20     }
21     return tim;
22 }
23 inline bool cmp(struct monster A,struct monster B){
24     if(A.average==B.average)
25         return A.atk>B.atk;
26     return A.average>B.average;
27 }
28 int main(){
29     ios::sync_with_stdio(0);
30     cin.tie(0);
31     cout.tie(0);
32     int T;
33     cin>>T;
34     LL sum_atk;
35     for (int i = 1; i <=T ; ++i) {
36         int n;
37         cin>>n;
38         sum_atk =0;
39         for (int i = 1; i <=n ; ++i) {
40             cin>>mon[i].hp>>mon[i].atk;
41             mon[i].alive= Alive(mon[i].hp);
42             mon[i].average = mon[i].atk*1.0/mon[i].alive;
43             sum_atk+=mon[i].atk;
44         }
45         LL hurt=0;
46         sort(mon+1,mon+n+1,cmp);
47         for (int i = 1; i <=n ; ++i) {
48             hurt+=sum_atk*mon[i].alive;
49             sum_atk-=mon[i].atk;
50         }
51         cout<<"Case #"<<i<<": "<<hurt<<endl;
52     }
53     return 0;
54 }

 

猜你喜欢

转载自www.cnblogs.com/hhyx/p/12543869.html
今日推荐