C - Maximum Median(有难度的思维题)

在这里插入图片描述
在这里插入图片描述
这道题,我一读很懵逼,我还以为是周期,结果队友给我解释了一下,居然可以用这么简单的方法来搞定;厉害我的队友!!(网上的二分我是真没明白QAQ)
首先来理解这道题吧:
题意:求对数组中任意元素经过K次操作(每次+1)之后排序,使得中位数最大,求这个最大的中位数是多少;
这道题,可以这样理解(把数字抽象成几何形状):
在这里插入图片描述
然后我们可以很清楚的知道:最优的选择肯定是每次填中间的数(因为如果你填后面的数,那中间的数还是中位数,不是吗?);那么如果中间的填满了就应该填第5个数,一次类推,我们可以知道一个细节,就是每次填中间的数时到了和它的右边的数相等的时候,那么按理说就应该是一起填上去,根据这个思路就知道如果,4,5填的一样多了,那么6就应该跟着走;
根据这个思路我可以发现:
在这里插入图片描述
那么如果所得到的和sum(就是每次需要一起升的高度的和(可以脑袋里面想一下))>k了那么就应该跳出循环;注意sum>k是sum有多余的一部分,所以多余的一部分应该减去,最后根据代码就可以理解了:(注意ll)
AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
int main(){
	ll n,k,a[maxn];
	scanf("%lld %lld",&n,&k);
	for(int i=0;i<n;i++)scanf("%lld",a+i);
	sort(a,a+n);
	ll mid=n/2,sum=0,z=1;
	for(int i=mid+1;i<n;i++){
		ll tt=(a[i]-a[i-1])*z;
		sum+=tt;
		if(sum>k){
			  sum-=tt;
			  break;
		}
		 z++;
	}
	ll ans=a[mid+z-1/*这里是对z减的,因为要满足a[]的下标*/]+(k-sum)/z;//这里k-sum是多出来的,因为可以想象到,z个的时候就已经平了,
	printf("%lld\n",ans);
	return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值