2024华为OD试题及答案-A060-最短木板长度

题目描述

小明有 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 )。

输出描述

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

用例
输入5 3
4 5 3 5 5
输出5
说明给第1块木板长度增加1,给第3块木板长度增加2后,
这5块木板长度变为[5,5,5,5,5],最短的木板的长度最大为5。
输入5 2
4 5 3 5 5
输出4
说明给第3块木板长度增加1后,这5块木板长度变为[4,5,4,5,5],剩余木料的长度为1。此时剩余木料无论给哪块木板加长,最短木料的长度都为4。

问题分析

  1. 题目理解

    • 给定 nnn 块木板,每块木板的长度为 aia_iai​。
    • 购买了一块长度为 mmm 的木料,可以将其切割成任意块并添加到已有的木板上。
    • 目标是使得最短的木板尽量长,求出加长木板后,最短木板的最大长度。
  2. 输入描述

    • 第一行包含两个正整数 nnn 和 mmm。
    • 第二行包含 nnn 个正整数 a1,a2,…,ana_1, a_2, \ldots, a_na1​,a2​,…,an​。
  3. 输出描述

    • 输出一个整数,表示加长木板后,最短木板的最大长度。
  4. 解题思路

    • 排序:先对木板长度数组进行排序。
    • 二分查找:通过二分查找尝试找到最短木板的最大长度。假设当前检查的长度为 midmidmid,计算将所有小于 midmidmid 的木板增加到 midmidmid 所需的总长度,并检查是否不超过 mmm。
    • 验证:对于每一个二分查找的中点值,计算当前需要的木料量,判断是否满足条件。

C++ 代码

 
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool canAchieveLength(vector<int>& boards, int n, int m, int mid) {
    int requiredWood = 0;
    for (int i = 0; i < n; ++i) {
        if (boards[i] < mid) {
            requiredWood += (mid - boards[i]);
        }
        if (requiredWood > m) {
            return false;
        }
    }
    return true;
}

int maxMinLength(vector<int>& boards, int n, int m) {
    sort(boards.begin(), boards.end());
    int left = boards[0], right = boards[n-1] + m;
    int result = left;

    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (canAchieveLength(boards, n, m, mid)) {
            result = mid;
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return result;
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<int> boards(n);
    for (int i = 0; i < n; ++i) {
        cin >> boards[i];
    }

    cout << maxMinLength(boards, n, m) << endl;

    return 0;
}

Python 代码

 
def can_achieve_length(boards, n, m, mid):
    required_wood = 0
    for board in boards:
        if board < mid:
            required_wood += (mid - board)
        if required_wood > m:
            return False
    return True

def max_min_length(boards, n, m):
    boards.sort()
    left, right = boards[0], boards[-1] + m
    result = left

    while left <= right:
        mid = left + (right - left) // 2
        if can_achieve_length(boards, n, m, mid):
            result = mid
            left = mid + 1
        else:
            right = mid - 1

    return result

if __name__ == "__main__":
    n, m = map(int, input().split())
    boards = list(map(int, input().split()))

    print(max_min_length(boards, n, m))

运行示例

假设输入如下:

 
5 3
4 5 3 5 5

运行上述程序可以得到输出:

 
5

这表示在给定的条件下,最短木板的最大长度可以达到 5。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值