【洛谷】P3887 世界杯 题解

[GDOI2014] 世界杯

世界杯

题目描述

3014 年世界杯足球赛就要开始了!作为卫冕冠军中国足球队的教练,手下每位球员都是猛将,如何摆出最强的 11 人阵容也是一件幸福的烦恼事啊。

众所周知,足球阵容里的11个球员都会被分配到场上某一个特别的位置,而这些位置主要分为守门员、后卫、中场和前锋四种,其中守门员有且只有一个,后卫、中场和前锋的人数取决于你安排的足球阵型。形容足球阵型的方法由后卫开始计算至前锋,但不把守门员计算在内。例如,3-5-2 阵型是指有三个后卫、五个中场及两名前锋。由于竞争激烈,每位球员只会培养其中一种位置所需要的技能,所以他们每个人都只能胜任四个位置中的其中一种。

作为一个对球员能力了如指掌的教练,你给每个球员的综合水平进行量化。为了将阵型安排得更好,你的教练团队决定使用以下策略安排球员:首先按照顺序提出 Q Q Q 个阵型,分别代表第一阵型、第二阵型、……、第 Q Q Q 阵型。然后对于每个阵型,从仍未选择的球员中选择最好的对应数量的守门员、后卫、中场和前锋。比如说,对于第一阵型,在所有球员中选择;对于第二阵型,在除了第一阵型外的所有球员中选择;对于第三阵型,在除了第一阵型和第二阵型外的所有球员中选择;以此类推。

现在 Q Q Q 个阵型都已经确定,而你需要知道的,是每个阵型的平均综合水平分别是多少。

输入格式

第一行有四个整数 K , D , M , F K, D, M, F K,D,M,F,分别表示守门员、后卫、中场和前锋供挑选的球员人数。

第二行有 K K K 个整数 k i k_i ki,分别表示每个守门员的综合水平值。

第三行有 D D D 个整数 d i d_i di,分别表示每个后卫的综合水平值。

第四行有 M M M 个整数 m i m_i mi,分别表示每个中场的综合水平值。

第五行有 F F F 个整数 f i f_i fi,分别表示每个前锋的综合水平值。

第六行有一个整数 Q Q Q,表示教练团队提出的阵型个数。

以下 Q Q Q 行,第 i i i 行三个整数 A i , B i , C i A_i, B_i, C_i Ai,Bi,Ci,由空格间隔,表示第 i i i 阵型是 A i − B i − C i A_i - B_i - C_i AiBiCi 阵型。

输出格式

输出 Q Q Q 行。对于第 i i i 种阵型,输出一个实数,表示该阵型平均综合水平的最大值,并四舍五入到小数点后 2 2 2 位。

样例 #1

样例输入 #1

3 10 12 4
76 60 87
78 84 84 84 81 82 72 51 77 57
85 84 62 87 88 64 81 90 80 66 88 85
65 83 63 79
2
4 5 1
4 4 2

样例输出 #1

85.64
78.00

提示

对于 30 % 30\% 30% 数据, K , D , M , F ≤ 1000 K, D, M, F≤1000 K,D,M,F1000 Q ≤ 10 Q≤10 Q10

对于 100 % 100\% 100% 数据, 1 ≤ K , D , M , F ≤ 1 0 5 1≤K, D, M, F≤10^5 1K,D,M,F105 0 ≤ k i , d i , m i , f i ≤ 1 0 8 0≤k_i, d_i, m_i, f_i≤10^8 0ki,di,mi,fi108 1 ≤ Q ≤ K 1≤Q≤K 1QK 0 ≤ A i , B i , C i ≤ 10 0≤A_i, B_i, C_i≤10 0Ai,Bi,Ci10 A i + B i + C i = 10 A_i+B_i+C_i=10 Ai+Bi+Ci=10 ∑ A i ≤ D ∑A_i≤D AiD ∑ B i ≤ M ∑B_i≤M BiM ∑ C i ≤ F ∑C_i≤F CiF

题解思路

将题目所求解释下:每个阵容根据不同位置人数需要,从尚未被阵容选中的球员中选择相应位置最强球员即可。
例如第一个样例:

3 10 12 4
守门员:76 60 87
后卫:78 84 84 84 81 82 72 51 77 57
中锋:85 84 62 87 88 64 81 90 80 66 88 85
前锋:65 83 63 79
2
4 5 1
4 4 2

我们需要组建两支球队。对于第一支球队的选择是:
第一,从守门员中选择最强的 1 1 1 名球员(之后其他阵容不能再使用)。第二,从后卫球员中选择最强的 4 4 4 名球员(之后其他阵容不能再使用)。第三,从中锋球员中选择最强的 5 5 5 名球员。第四,从前锋球员中选择最强的 1 1 1 名球员。挑选完 11 11 11 名球员后,算出他们的能力的平均值。

为了保证选出的是当前未被选择的最强球员,可以有两种办法:1、每个位置的球员能力值进行排序,按顺序选取。2、使用优先队列,这样放入队列的数一定是有序的。优先队列可以根据需要,从大到小排列,或从小到大排列。题解给出的是使用数组排序的做法。

题解代码

#include <bits/stdc++.h>
using namespace std;

int k, d, m, f, q;
const int N = 100003;
int defender[N], back[N], mid[N], before[N];
// 从大到少排序
bool cmp(int a, int b)
{
    return a > b;
}

int main()
{
    scanf("%d%d%d%d", &k, &d, &m, &f);
    for (register int i(0); i < k; ++i)
    {
        scanf("%d", &defender[i]);
    }
    for (register int i(0); i < d; ++i)
    {
        scanf("%d", &back[i]);
    }
    for (register int i(0); i < m; ++i)
    {
        scanf("%d", &mid[i]);
    }
    for (register int i(0); i < f; ++i)
    {
        scanf("%d", &before[i]);
    }
    scanf("%d", &q);
    sort(defender, defender + k, cmp);
    sort(back, back + d, cmp);
    sort(mid, mid + m, cmp);
    sort(before, before + f, cmp);
    int w = 0, x = 0, y = 0, z = 0;
    int a, b, c;
    double sum = 0;
    for (register int i(0); i < q; ++i)
    {
        scanf("%d%d%d", &a, &b, &c);
        sum = 0;
        sum += defender[w]; // 守门员
        ++w;
        for (register int j(x); j < x + a; ++j)
        {
            sum += back[j]; // 后卫
        }
        x += a;
        for (register int j(y); j < y + b; ++j)
        {
            sum += mid[j]; // 中锋
        }
        y += b;
        for (register int j(z); j < z + c; ++j)
        {
            sum += before[j]; // 前锋
        }
        z += c;
        printf("%.2f\n", sum / 11);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值