洛谷P3887 [GDOI2014] 世界杯


前言

这题主要考查模拟,想一想如何使用优先队列做出这道题。

看完提示的同学可以先再想一想如何解出这道题


一、题目

P3887 [GDOI2014] 世界杯

在这里插入图片描述


二、解题过程

1.解题思路

(1)分别将守门员,后卫,中场和前场的综合水平值存入四个大根堆,确保每次都可以取到综合水平值最高的人。

(2)然后循环q次输入a,b,c,每次取出1位综合水平值最大的守门员,取出a位综合水平值最大的后卫,取出b位综合水平值最大的中场,取出c位综合水平值最大的前锋。

(3)最后除以11.0得到该阵型的平均综合水平,继续循环。


2.代码

#include <bits/stdc++.h>
#include <iostream>  
#include <vector>  
#include <algorithm>  
#include <iomanip>  
using namespace std;  
// 快读模板  
long long read() {  
    long long x = 0, f = 0;  
    char ch = getchar();  
    while (ch < '0' || ch > '9') f |= ch == '-', ch = getchar();  
    while ('0' <= ch && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();  
    return f ? -x : x;  
}  
// 快写模板  
void write(long long x) {  
    if (x < 0) putchar('-'), x = -x;  
    if (x > 9) write(x / 10);  
    putchar(x % 10 + '0');  
}  
const int N = 1e5 + 10;  
//大根堆priority_queue<int>a
//小根堆priority_queue<int, vector<int>, greater<int>>b
priority_queue<int> kp, dp, mp, fp;//分别建立四个大根堆(优先队列)
void init(priority_queue<int>&p, int n) {
    for (int i = 0; i < n; ++i){
        p.push(read());
    }
}
int main(){
    long long k, d, m, f, q;  
    cin >> k >> d >> m >> f;
    init(kp,k);//守门员数值
    init(dp,d);//后卫数值
    init(mp,m);//中场数值
    init(fp,f);//前锋数值
    cin >> q;
    while (q--){
        long long a, b, c;  
        a = read(), b = read(), c = read();
        double ans = kp.top();//取出一位综合水平值最大的守门员
        kp.pop();
        for (int i = 0; i < a; ++i){//取出a位综合水平值最大的后卫  
            if(dp.empty()) break;
            ans += dp.top();
            dp.pop();
        }
        for (int i = 0; i < b; ++i){//取出b位综合水平值最大的中场
            if(mp.empty()) break;
            ans += mp.top();
            mp.pop();
        }
        for (int i = 0; i < c; ++i){//取出c位综合水平值最大的前锋
            if(fp.empty()) break;
            ans += fp.top();
            fp.pop();
        }  
        ans /= 11.0;//取综合水平值平均值
        cout << fixed << setprecision(2) << ans << '\n';//保留两位小数输出  
    }
    return 0;  
}

如果觉得对你有所帮助的话,请点个免费的赞吧!

  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值