题目:https://vjudge.net/problem/CodeForces-1201C
思路:这个题吧——可以进行k次让任意一个数+1,求最大的中位数。因为是只有+1的操作,所以只存在中位数和它前面的原本比他大数进行交换位置。所以我们只考虑 这个范围内的数就行了。后期就可以用于一种类似于填坑的思路来做。
假设我们处理到了范围 。
首先肯定是希望数都尽量大,并且保证我们的中位数一直都是中位。如果是这样的一个样例:
5 8
1 2 3 4 10
3和4,3可以和4齐平,用1次操作变成;剩余操作次数9次;
而后两个4一起看,后一个数是10,但是要齐平就需要12次操作,所以我们就可以在10以内让这两个数尽量大,也就是再用8次操作变成:,最大的中位数就是8了。还剩一次操作是没有意义的。
所以就可以得出结论:
如果可以和下一个数齐平,那就一起填上去;如果不够了,那就一起尽量变大,并停止操作就可以了。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
ll n,k;
const ll INF=2e5+5;
ll a[INF];
int main()
{
scanf("%lld%lld",&n,&k);
ll i,j,val;
for(i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
sort(a+1,a+1+n);
ll mid=n/2+1;
for(i=mid+1;i<=n;i++)
{
if((a[i]-a[i-1])*(i-mid)<=k)
{
k=k-(a[i]-a[i-1])*(i-mid);
}
else {
break;
}
}
if(i<=n)
{
val=a[i-1]+k/(i-mid);
}
else {
val=a[n]+k/(n/2+1);
}
printf("%lld",val);
return 0;
}