bluecode-2024E-最短木板长度

155 阅读2分钟

时间限制:C/C++ 1000MS,其他语言 2000MS
内存限制:C/C++ 128MB,其他语言 256MB
难度:中等
分数:100 OI排行榜得分:14(0.1分数+2难度)

描述

小明有 n 块木板,第 i ( 1 ≤ i ≤ n ) 块木板长度为 ai。
小明买了一块长度为 m 的木料,这块木料可以切割成任意块,拼接到已有的木板上,用来加长木板。
小明想让最短的木板尽量长。请问小明加长木板后,最短木板的长度可以为多少?

输入描述

输入的第一行包含两个正整数, n ( 1 ≤ n ≤ 10^3 ), m ( 1 ≤ m ≤ 10^6 ),n 表示木板数, m 表示木板长度。
输入的第二行包含 n 个正整数, a1, a2,…,an ( 1 ≤ ai ≤ 10^6 )。

输出描述

输出的唯一一行包含一个正整数,表示加长木板后,最短木板的长度最大可以为多少?

用例输入 1 **

5 3
4 5 3 5 5

用例输出 1 **

5

用例说明 1 **

给第1块木板长度增加1,给第3块木板长度增加2后,这5块木板长度变为[5,5,5,5,5],最短的木板的长度最大为5

用例输入 2 **

5 2
4 5 3 5 5

用例输出 2 **

4

用例说明 2 **

给第3块木板长度增加1后,这5块木板长度变为[4,5,4,5,5],剩余木料的长度为1。此时剩余木料无论给哪块木板加长,最短木料的长度都为4
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

bool check(vector<int>& a, int m, int mid) {
    int required = 0;
    for (int num : a) {
        if (num < mid) {
            required += mid - num;
        } else {
            break; // 已排序,后面的都不需要处理
        }
    }
    return required <= m;
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<int> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    sort(a.begin(), a.end());

    int left = a[0];
    int right = a[0] + m;
    int ans = left; // 初始化为原始最小值

    while (left <= right) {
        int mid = (left + right) / 2;
        if (check(a, m, mid)) {
            ans = mid;
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }

    cout << ans << endl;
    return 0;
}