练习cf1201C. Maximum Median

题目如下
C. Maximum Median
time limit per test2 seconds
memory limit per test256 megabytes
You are given an array 𝑎 of 𝑛 integers, where 𝑛 is odd. You can make the following operation with it:

Choose one of the elements of the array (for example 𝑎𝑖) and increase it by 1 (that is, replace it with 𝑎𝑖+1).
You want to make the median of the array the largest possible using at most 𝑘 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 𝑛 and 𝑘 (1≤𝑛≤2⋅105, 𝑛 is odd, 1≤𝑘≤109) — the number of elements in the array and the largest number of operations you can make.

The second line contains 𝑛 integers 𝑎1,𝑎2,…,𝑎𝑛 (1≤𝑎𝑖≤109).

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

题目大意
现有n个数组成数组,可以对任意数组元素进行加一操作,最多进行k次,怎么操作使得数组的中位数最大,输出最大的中位数。

题目分析
要使得中位数最大,那么排序后中位数不进行任何操作的情况下至少是a[mid],假设k次操作可以全部用在a[mid]上,那么中位数至多只能是a[mid] + k,这种情况是可能存在的,确定了中位数的范围在[a[mid],a[mid] + k]。
那么设立双指针分别是left = a[mid], right = a[mid] + k,采用二分法在满足a[mid]比后续任何一个元素都小且操作数小于等于k的前提下,不断缩小范围找到中位数的最大可能。

点击查看代码
int mid = n / 2;
    long long left = a[mid], right = a[mid] + k ;
    while(left <= right){
        long long m = (left + right) / 2;
        unsigned long long cost = 0; //累计花费的操作数
        for(int i = mid; i < n; i++){
            if(a[i] < m){
                cost += (m - a[i]);
            }
        }
        if(cost <= k){
            left = m + 1;
        }else{
            right = m;
        }
    }

完整代码

点击查看代码
#include <vector>
#include <algorithm>
using namespace std;
int main(){
    int n;
    unsigned long long k;
    scanf("%d %llu", &n, &k);
    vector<long long> a;
    for(int i = 0; i < n; i++){
        long long num;
        scanf("%lld", &num);
        a.push_back(num);
    }
    sort(a.begin(),a.end());
    int mid = n / 2;
    long long left = a[mid], right = a[mid] + k + 1;
    while(left < right){
        long long m = (left + right) / 2;
        unsigned long long cost = 0; //累计花费的操作数
        for(int i = mid; i < n; i++){
            if(a[i] < m){
                cost += (m - a[i]);
            }
        }
        if(cost <= k){
            left = m + 1;
        }else{
            right = m;
        }
    }
    printf("%lld\n", left - 1);
    return 0;
}

posted @ 2025-07-15 20:46  sirro1uta  阅读(18)  评论(0)    收藏  举报