首页 > 编程语言 > 详细

【比值排序】 Kill the monster

时间:2020-06-20 09:40:51      阅读:100      评论:0      收藏:0      [点我收藏+]

题解

\(n\)个怪兽,每个怪兽有\(hp\)血量和\(atk\)攻击值,每一秒英雄都会受到所有存活怪兽的攻击,英雄攻击每个怪兽的伤害等于攻击当前怪兽的次数,第一次攻击第i个怪兽的伤害为\(1\),第二次为\(2\),计算英雄杀光所有怪兽后承受的最小攻击
数据范围:
\(T:10^{3}\)
\(n:(1,10^{5})\)
所有测试数据的\(n\)的和\(<10^{6}\)
\(1\leq Hp,atk \leq 10^{5}\)

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

Code

#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N=1e5+10;
struct monster{
    LL hp;
    LL atk;
    LL alive;//预处理所有怪兽从被攻击开始能够存活的时间
    double average;//存活时间内的平均攻击
}mon[N];
inline LL Alive(LL x){
    LL tim,res=0;
    for (int i = 1;; ++i){
        res+=i;
        if(res>=x){
            tim=i;
            break;
        }
    }
    return tim;
}
inline bool cmp(struct monster A,struct monster B){
    if(A.average==B.average)
        return A.atk>B.atk;
    return A.average>B.average;
}
int main(){
    int T;
    cin>>T;
    LL sum_atk;
    for (int i = 1; i <=T ; ++i) {
        int n;
        cin>>n;
        sum_atk =0;
        for (int i = 1; i <=n ; ++i) {
            cin>>mon[i].hp>>mon[i].atk;
            mon[i].alive= Alive(mon[i].hp);
            mon[i].average = mon[i].atk*1.0/mon[i].alive;
            sum_atk+=mon[i].atk;
        }
        LL hurt=0;
        sort(mon+1,mon+n+1,cmp);
        for (int i = 1; i <=n ; ++i) {
            hurt+=sum_atk*mon[i].alive;
            sum_atk-=mon[i].atk;
        }
        cout<<"Case #"<<i<<": "<<hurt<<endl;
    }
    return 0;
}

【比值排序】 Kill the monster

原文:https://www.cnblogs.com/hhyx/p/13167256.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!