题意:题目给出一段序列,我们要将该序列排序,然后当前它有一个中位数,我们有k次操作机会,每一次操作时,我们可以随便选一个地方加1。最后我们要使得我们的中位数是最大的。我们该如何去做呢。就题中所给的例子,1,3,5.操作机会是2,我们对比3,5.发现其刚好相差于2,我们把两次机会都加到3上,最后的序列为1,5,5.这个时候中位数,就为最大为5.那对于1,2,3,5,6.这组序列,我们有四次操作机会,我们从中位数开始遍历,这个时候发现5,大于3,我们尽可能把3加到最大为5,这个时候损失了两次机会。之后遍历到6,我们发现6,大于5,我们还剩两次机会,我们就可以,将两次机会加到,5,5,上使得最终序列变为,1,2,5,5,6.我们的剩余机会变为0得到最终答案。
思路:我们先将序列按从小到大排序,我们从中位数+1开始,开始操作。具体如图。
最后我们得出规律,我们每一次都要在mid+num与mid之间的每一个位置进行加1操作。操作机会损失为(num[mid+num]-num[mid] )*num;如果我们发现操作机会小于(num[mid+num]-num[mid] )*num。我们就结束循环。最后我们要输出num[mid]+k/剩余机会数。我们还有可能在加几遍。是因为操作机会可能小于(num[mid+num]-num[mid] )*num。
代码如下:
#include<bits/stdc++.h>
using namespace std;
long long num1,num2;
int main()
{
while(cin>>num1>>num2)
{
long long a[num1];
for(long long i=0;i<num1;i++)cin>>a[i];
sort(a,a+num1);
long long mid=num1/2;
long long index=1;
while(mid+index<num1&&num2>(a[mid+index]-a[mid])*index)
{
num2-=(a[mid+index]-a[mid])*index;
a[mid]=a[mid+index];
index++;
}
cout<<a[mid]+num2/index<<endl;
}
}