C. Maximum Median 二分

C. Maximum Median

题意: 给定一个数组,可每次可以选择一个数加1,共执行k次,问执行k次操作之后这个数组的中位数最大是多少?

题解:首先对n个数进行排序,我们只对大于中位数a[n/2]的数进行操作,所以这个最大中位数的取值范围是确定的,在区间[  [a[n/2],a[n-1]  ]之内,二分枚举最大的中位数x;

通过判断使x成为最大中位数的操作数是否大于k来缩小范围

#include<iostream>
#include<string.h>
#include<string>
#include<algorithm>
#include<math.h>
#include<string>
#include<string.h>
#include<vector>
#include<utility>
#include<map>
#include<queue>
#include<set>
#define mx 0x3f3f3f3f
#define ll long long
using namespace std;
ll a[200005];
ll n,k;
int find(ll x)
{
    ll num=0;
    for(int i=n/2;i<n;i++)
    {
        if(a[i]<=x)//对所有比中位数小的答案进行增加操作,num记录操作次数
            num=num+x-a[i];
    }
    if(num<=k)
        return 1;
    else
        return 0;
}
int main()
{
    cin>>n>>k;
    for(int i=0;i<n;i++)
        cin>>a[i];
    sort(a,a+n);
    ll t=0;
    ll l=a[n/2],r=a[n-1]+k,mid,ans;
    while(l<=r)//二分枚举最大的中位数x,x在区间[l,r]中
    {
        mid=l+(r-l)/2;
        if(find(mid)==1)//mid偏小
        {
            l=mid+1;
            ans=mid;
        }
        else
            r=mid-1;
    }
    cout<<ans<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/-citywall123/p/11393617.html

时间: 2024-08-04 13:51:23

C. Maximum Median 二分的相关文章

POJ 3579 Median 二分+思维

POJ 3579 Median 二分+思维 题意 给你一些数,然后求这些数相互之间差的绝对值,然后绝对值排序,找到中间那个数. 解题思路 我反正一直开始是没有想到这个题竟然可以用二分来做.━━( ̄ー ̄*|||━━. 二分枚举答案,假设枚举值为mid,然后就是在排好序的序列中对每一个num[i]找到在i之后,有多少个大于num[i]+mid的数的个数(数列里的值比num[i]+mid大,说明该值与num[i]作差形成的新数列里的数比中位数mid大),用lower_bound计算所有差值比mid大于

POJ3579 Median(二分答案 + O(N)判定)

传送门 大意:给出N个数,对于存有每两个数的差值的序列求中位数,如果这个序列有偶数个元素,就取中间偏小的作为中位数. 因为N<=100000,所以想要求出每一个差值是不可行的,我们很容易想到二分答案. 在二分答案时我们会进行判定,求出小于等于枚举值的个数,我看其他人的判定似乎都是O(NlogN) 的,我在这里就给出一个O(N)的判定方法. 首先同样将数组排序(我们命名为a数组好了) 我们枚举一个区间[l,r),因为当r增加的时候,要使[l,r)中的数都大于于等于a[r]?枚举值,l必定不会增加,

poj 3579 Median 二分查找与lower_bound

题意: 给n个数,他们两两之间较大数减去较小数总共有n*(n-1)/2个数,要求这些数的中位数. 分析: 两次二分,第一次枚举答案,第二次判断该数是否可能成为中位数. 代码: //poj 3579 //sep9 #include <iostream> #include <algorithm> using namespace std; const int maxN=1e5+10; int a[maxN]; int n,m; int test(int x) { int sum=0; f

POJ3579 Median —— 二分

题目链接:http://poj.org/problem?id=3579 Median Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8286   Accepted: 2892 Description Given N numbers, X1, X2, ... , XN, let us calculate the difference of every pair of numbers: ∣Xi - Xj∣ (1 ≤ i < 

【CF1201C】Maximum Median

题意: 给定一个长度为 $n$ 的序列,并得到了 $k$ 次操作的机会,每一次操作就是把其中一个数的值加 $1$. 求合理安排这 $k$ 次操作,使得结果序列的中位数最大. $1 \le n \le 2*10^5,1 \le k \le 10^9$ 分析: 我们可以用贪心策略想,如果给原始序列小于中位数的数进行操作,那么答案肯定不是最优的,不如给较大的数字. 所以,我们可以删去这个序列中所有小于中位数的数. 删去之后,那原来的中位数就变成了这个序列中最小的数了. 问题便转换成 “最小值最大” 这

POJ - 3579 Median 二分

题目大意:给出n个数,要求将这n个数两两相减,把这些相减得到的数排序后,输出位置在中间的那个数 解题思路:如果两两相减再排序复杂度太高,肯定超时了,不妨换另一种思路 枚举最中间的那个数,然后判断一下相减得到的数有多少个大于等于枚举的数 如何判断上面所说的那句呢,其实不用把每个数相减,只需要排序一下,然后将当前这个数 + 枚举的那个数,然后在数组中找到大于等于这个数的第一个位置(lower_bound()),再用n减去那个数的位置就可以知道有多少个相减的结果会大于等于这个数了 最后只需要判断一下大

Moo University - Financial Aid (poj 2010 优先队列 或者 二分)

Language: Default Moo University - Financial Aid Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5551   Accepted: 1663 Description Bessie noted that although humans have many universities they can attend, cows have none. To remedy this p

Codeforces Round #577 (Div. 2) (A、B、C)

A.Important Exam 简单贪心即可 1 #include<iostream> 2 #include<sstream> 3 #include<fstream> 4 #include<algorithm> 5 #include<cstring> 6 #include<iomanip> 7 #include<cstdlib> 8 #include<cctype> 9 #include<vector&

Poj 2010-Moo University - Financial Aid

Moo University - Financial Aid 题目链接:http://poj.org/problem?id=2010 Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 9046   Accepted: 2640 Description Bessie noted that although humans have many universities they can attend, cows have none