CodeForces-1201C(思维)

题目:https://vjudge.net/problem/CodeForces-1201C

思路:这个题吧——可以进行k次让任意一个数+1,求最大的中位数。因为是只有+1的操作,所以只存在中位数和它前面的原本比他大数进行交换位置。所以我们只考虑 [{mid}, n] 这个范围内的数就行了。后期就可以用于一种类似于填坑的思路来做。

假设我们处理到了范围  [mid, now]  (now <= n) 。

首先肯定是希望数都尽量大,并且保证我们的中位数一直都是中位。如果是这样的一个样例:

5 8

1 2 3 4 10

3和4,3可以和4齐平,用1次操作变成;剩余操作次数9次;

而后两个4一起看,后一个数是10,但是要齐平就需要12次操作,所以我们就可以在10以内让这两个数尽量大,也就是再用8次操作变成:,最大的中位数就是8了。还剩一次操作是没有意义的。

所以就可以得出结论:

如果可以和下一个数齐平,那就一起填上去;如果不够了,那就一起尽量变大,并停止操作就可以了。

AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
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;
}


 

你可能感兴趣的:(思维)