组队竞赛
牛牛举办了一次编程比赛,参加比赛的有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(1 ≤ n ≤ 10^5)
第二行包括3*n个整数a_i(1 ≤ a_i ≤ 10^9),表示每个参赛选手的水平值.
输出描述:
输出一个整数表示所有队伍的水平值总和最大值.
示例:
输入:
2
5 2 8 5 1 5输出:
10
根据题目的描述,总结下来就是需要输入一个n表示n组,输入3*n个数据表示每个队员的水平值,然后再3人一组,最后对n个组的第二大水平值进行求和即可。
- 将3n个数据排序
- 最小的n个数必定是每组的第三水平值
- 最大的n个数必定是每组的第一水平值
- 取中间n个数求和即可
上述思路就是我看到此题目的第一反映,然后就报错了。。。。
我们拿题目数据分析:
按上述说法去头去尾取到中间的5+5=10,乍一看好像又没有问题(没错,我就是这么被骗的,然后惨遭报错)
我们换下面一组数据:
去头去尾取4+5+6=15,但是我们看这样一个分组:
取的值8+6+4=18是比我的那种更优的,斟酌思考后发现了我的问题所在:我的思路直接舍弃掉了次大的数据,使用两大带一小的取法可以让次大的数据保留下来从而提高水平值,进一步使得水平值总和更大。
正确思路:
- 将3n个数据排序
- 从第n+1个数隔1取1
ps:如上述1-9,从4开始取隔一个5取6,再隔一个7取8即可
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;int main()
{int n;vector<int> score;while(cin>>n)//支持循环输入{//设置vector的大小size(3*n);for(int i=0;i<score.size();i++){cin>>score[i];}//算法库中的排序算法,默认升序sort(score.begin(),d());//由于给定的分数范围1 ≤ a_i ≤ 10^9,int类型可能会超出范围导致跑不过long long sum=0;//前n个是最小的数据直接从第n+1个数据隔2相加(中间的那个数字是一组的最高水平)for(int i=n;i<3*n;i+=2){sum+=score[i];}cout<<sum;}return 0;
}
关于我看到的题解,前面一直到排序都是基本一样,但是在选择数据的时候题解采用的方式好像又不太一样:
我的:
for(int i=n;i<3*n;i+=2)
{sum+=score[i];
}题解:
for(int j=0;j<n;j++)
{sum+=score[score.size()-2*(j+1)];
}
目前我也不是很能理解这个公式的原理,后续理解了再更新一下吧。
本文发布于:2024-02-01 16:26:04,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170677596437933.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |