博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
codeforces 1201 C Maximum Median 二分
阅读量:718 次
发布时间:2019-03-21

本文共 1033 字,大约阅读时间需要 3 分钟。

在这里插入图片描述

在这里插入图片描述

洛谷翻译

在这里插入图片描述

思路

1.拿到题的时候没有思路先模拟样例,看第二个样例,1 2 1 1 1,原来的数组,1 1 1 1 2 中位数是1,我们要想使中位数最大,就尽可能的给中位数+1,但是同时要满足它是中位数,也就是说,中位数1后边的数也要维护,我们现在给中位数+1, 变成 1 1 2 1 2 ,要满足这个数组成立,那么就要给2后边的1也进行+1的操作,变成1 1 2 2 2 继续 1 1 3 2 2 ,维护 1 1 3 3 3 ,这样5次操作刚好用完,中位数最大就是3

2.如果代码也是这样模拟,肯定超时,应为光k就是1e9,我们继续观察,其实将原数组排序后维护仅仅是中位数和其后边的数,前边的数可以不用考虑,那么我们是否可以枚举 a[index] (代表中位数) 到 a[index]+k 之间的数,判断其符合条件

3.check函数怎么写 :现在中位数就是x,我们判断x满足条件就可以了,看中位数及其以后的数组,只要是小于x的,都需要进行维护,维护的就是x-a[i],如果维护的总和大于了k,说明这个x不可取

4.check函数里的判断不能求总和再判断,要执行减的操作,好好观察数据,会爆long long 的,我这里wa了好多次才注意到,好坑啊

AC代码

#include
using namespace std;typedef long long ll;const int N = 2e5 + 10;ll a[N];ll n, k, sum,index;bool check(ll x) {
//判断其时候满足条件 ll cnt=k; for(int i=index;i<=n;i++){
if(a[i]
> n >> k; for (int i = 1; i <= n; i++) {
scanf("%lld", &a[i]); } if (n == 1) {
//特判 1 cout << ll(a[1] + k) << endl; } else {
sort(a + 1, a + 1 + n); index=(n+1)/2; //求中位数的下标(从1开始的) cout << bsearch() << endl; } return 0;}

转载地址:http://wkgrz.baihongyu.com/

你可能感兴趣的文章