CF#618 div2 B
题目:
提醒:奇数元素数组[a1,a2,…,a2k+1]的中值定义如下:让[b1,b2,…,b2k+1]按排序顺序作为数组元素。这个数组的中值等于bk+1。
有2n名学生,第1名学生的技能水平为a[i]。并不能保证所有的技能水平都是不同的。
我们把一个班的技能水平定义为该班学生技能水平的中位数。
作为学校的校长,你想把每个学生分配到两个班级中的一个,这样每个班级都有奇数个学生(不能被2整除)。根据你的选择,班上的学生人数可以是相等的,也可以是不同的。每个学生必须被分配到一个班级。在这些分区中,您希望选择一个将类的技能级别之间的绝对差异最小化的分区。
你能达到的最小绝对差是多少?
输入
每个测试包含多个测试用例。第一行包含测试用例的数量t(1≤t≤104)。下面是对测试用例的描述。
每个测试用例的第一行包含一个整数n(1≤n≤105)-学生人数减半。
每个测试用例的第二行包含2n个整数a1,a2,…,a2n(1≤ai≤109)-学生的技能水平。
保证所有测试用例的n之和不超过105。
注意
在第一个测试中,只有一种方法来划分学生-每个班级一个。技能等级的绝对差异将为1-1=0。
在第二个测试中,一个可能的划分是使第一类学生的技能水平为[6,4,2],这样第一类学生的技能水平为4,第二类学生的技能水平为[5,1,3]。绝对差为| 4−3 |=1。
注意,不能像[2,3]、[6,5,4,1]或[]、[6,5,4,1,2,3]这样分配,因为班级的学生数是偶数。[2][1,3,4]也不可能,因为技能5和6的学生没有被分配到一个班级。
在第三个测试中,您可以按以下方式分配学生:[3,4,13,13,20],[2,5,8,16,17]或[3,8,17],[2,4,5,13,13,16,20]。两个分区都给出最小的可能绝对差。
思路:
猜测用vector容器储存1e10数据
然后排序
按照1 3 5 7…和2 4 6 8…的顺序分别抽取
然后取两个数组的中间值相减
答案AC,如何证明这个贪心思路呢
#include<bits/stdc++.h>
using namespace std;
vector<int> a;
int t;
int n;
int x;
int main()
{
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=2*n;i++)
{
cin>>x;
a.push_back(x);
}
sort(a.begin(),a.end());
if(n==1)
{
cout<<a[1]-a[0]<<endl;
}
else
{
cout<<a[n]-a[n-1]<<endl;
}
a.clear();
}
}
//1 2 3 4 5 6
//2 3 4 5 8 13 13 16 17 20
你这个取的思路实际上结果就是直接在拿中间两个数做差,随便取两个位置假装是中位数,不难发现这两个数越靠近差值越小,所以最小的时候必然相邻,然后这两个数都要是是中位数,那么他们左右两边的数的个数应该要一样多,所以就是中间两个数了,所以答案就是排好序之后的a[n+1]-a[n]
ok
https://codeforces.com/contest/1300