前言
这题主要考查模拟,想一想如何使用优先队列做出这道题。
看完提示的同学可以先再想一想如何解出这道题
一、题目
二、解题过程
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;
}
如果觉得对你有所帮助的话,请点个免费的赞吧!