组队竞赛
题目描述
题目链接:组队竞赛
牛牛举办了一次编程比赛,参加比赛的有3*n个选手,每个选手都有一个水平值a_i.现在要将这些选手进行组队,一共组成n个队伍,即每个队伍3人.牛牛发现队伍的水平值等于该队伍队员中第二高水平值。
例如:
一个队伍三个队员的水平值分别是3,3,3.那么队伍的水平值是3
一个队伍三个队员的水平值分别是3,2,3.那么队伍的水平值是3
一个队伍三个队员的水平值分别是1,5,2.那么队伍的水平值是2
为了让比赛更有看点,牛牛想安排队伍使所有队伍的水平值总和最大。
如样例所示:如果牛牛把6个队员划分到两个队伍
如果方案为:team1:{1,2,5}, team2:{5,5,8}, 这时候水平值总和为7.
而如果方案为:team1:{2,5,8}, team2:{1,5,5}, 这时候水平值总和为10.
没有比总和为10更大的方案,所以输出10.
输入输出示例及描述
输入输出描述
输入的第一行为 一个正整数n
输入的第二行包括 3*n个整数 a_i ,表示每个参赛选手的水平值.
数据范围
1 ≤ n ≤ 10^5
1 ≤ a_i ≤ 10^9
示例1
输入:
2 5 2 8 5 1 5
输出:
10
解题思路及源码
思路:
- 本题考察的是贪心算法
- 关键思路在于要保证每组的第二个值取到能选择的最大值就可以,我们每次尽量取最大,但是最大的数不可能是中位数,所以退而求其次,取每组中第二大的数
- 将选手值进行排序,前n个最小值直接作为每组中的第一个值
- 后2n个已经排序好的数中,取n,n+2,n+4,n+6,…作为每一组的第二大的数
- 将这些第二大的数求和,就是最终答案
解法一:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
int n;
while (cin >> n)
{
long long sum = 0; //保存答案
vector<int> a; //存放 选手水平值
a.resize(3*n);
// 读取水平值
for (int i = 0; i < (3 * n); i++) {
cin >> a[i];
}
// 将选手水平值从小到大排序
std::sort(a.begin(), a.end());
// 取出 后2n个数 中的所有 偶数位置 上的数,求和
for (int i = n; i <= 3 * n - 2; i += 2)
{
sum += a[i];
}
cout << sum << endl;
}
}