CodeForces - 1201C Maximum Median 二分查找

思路来源:https://blog.csdn.net/dream_it_/article/details/98511000
题意:给你n(n为奇数)个数的一个排列,然后你可以做k次操作,让操作之后的中位数尽可能的大。每操作的内容是:任选一个数,让它加一。
思路:
1、中位数自然是排序后最中间的数,这里是奇数序列,自然就是最中间的那个数。然后二分查找。
2、二分查找的方法:先排序,再确定二分的上下界。这里的下界就是当前的中位数的值a[mid],上界就是a[mid]+k。
3、然后二分枚举上下界之间每一个数m,判断这个数m是否合适(是否满足是操作之后最大的中位数)。
4、这里需要用一个函数来判断这个数是否合适。先判断枚举的数m是否大于当前a[mid],若等于,就说明当前这个数小了或者刚好合适,那么就返回让下界收缩;若大于,则从i从mid开始,a[i]开始往后轮,计算一下所有小于当前m的a[i]与m的差值的和。(如 序列是 1 2 3 4 5 6 7,枚举的m是6,那么就从4开始 计算一下所有小于6的值a[4] a[5]…与6的差值之和,看看是否大于k,就是说你枚举的m要不大不小,正好让a[mid]开始的几个数与m的差值把k消耗掉了,那枚举的这个m就是要求的最终中位数)。
5、不断收缩区间最后获得最大中位数。
上ac代码 是思路来源里面的代码,我自己又加了一句剪枝,就是在计算差值之和时,如果当前值不小于m了,直接退出。加了这句试了也可以ac。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
int n, k, index, a[200005];
bool check(ll m) {
	if (a[index] >= m){
		return true;
	}
	ll sum = 0;
	for (int i = index; i <= n; i++){
		if (a[i] < m){
			sum += (m - a[i]);
		}else break;
		if (sum > k) return false;
	}
	return true;
}
int main() {
	scanf("%d%d", &n, &k);
	for (int i = 1; i <= n; i++){
		scanf("%d", &a[i]);
	}
	sort(a + 1, a + n + 1);
	index = (n + 1) >> 1;//中位数坐标为index
	ll l = a[index];
	ll r = a[index] + k;//在mid 到mid+k之间二分查找
	ll ans;
	while (l <= r){//l 和r 是中位数的范围
		ll m = (l + r) >> 1;//二分查找中位数
		if (check(m)){//若当前的这个m可以
			ans = m;
			l = m + 1;
		} else{
			r = m - 1;
		}
	}
	printf("%lld\n", ans);
	return 0;
}

最后放题目,以防搜题的人百度搜不到我啊哈哈哈哈 还可以防止一开头都是题目的视觉污染啊哈哈哈哈我太机智了
You are given an array a of n integers, where n is odd. You can make the following operation with it:

Choose one of the elements of the array (for example ai) and increase it by 1 (that is, replace it with ai+1).
You want to make the median of the array the largest possible using at most k operations.

The median of the odd-sized array is the middle element after the array is sorted in non-decreasing order. For example, the median of the array [1,5,2,3,5] is 3.

Input
The first line contains two integers n and k (1≤n≤2⋅105, n is odd, 1≤k≤109) — the number of elements in the array and the largest number of operations you can make.

The second line contains n integers a1,a2,…,an (1≤ai≤109).

Output
Print a single integer — the maximum possible median after the operations.

Examples
Input
3 2
1 3 5
Output
5
Input
5 5
1 2 1 1 1
Output
3
Input
7 7
4 1 2 4 3 4 4
Output
5
Note
In the first example, you can increase the second element twice. Than array will be [1,5,5] and it’s median is 5.

In the second example, it is optimal to increase the second number and than increase third and fifth. This way the answer is 3.

In the third example, you can make four operations: increase first, fourth, sixth, seventh element. This way the array will be [5,1,2,5,3,5,5] and the median will be 5.
题目来源:http://codeforces.com/problemset/problem/1201/C

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值