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


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值