华为OD机试 - 数据最节约的备份方法 - 二分查找(Java 2023 B卷 100分)

在这里插入图片描述

目录

    • 一、题目描述
    • 二、输入描述
    • 三、输出描述
    • 四、解题思路
      • 解题思路如下:
      • 解题思路分析:
    • 五、Java算法源码
    • 六、效果展示
      • 1、输入
      • 2、输出
      • 3、说明

华为OD机试 2023B卷题库疯狂收录中,刷题点这里

一、题目描述

有若干个文件,使用刻录光盘的方式进行备份,假设每张光盘的容量是500MB。

求使用光盘最少的文件分布方式,所有文件的大小都是整数的MB,且不超过500MB,文件不能分隔、分卷打包。

二、输入描述

每组文件大小的数据。

三、输出描述

使用光盘的数量。

四、解题思路

题目要求找出使用光盘最少的文件分布方式,使得所有文件都能被备份,每张光盘的容量为500MB。文件的大小都是整数的MB,且不超过500MB。

解题思路如下:

  1. 读取输入的每组文件大小的数据,并将其转换为整数数组;
  2. 对文件的大小进行升序排序,以便从小到大进行分配;
  3. 使用二分查找确定最少的光盘数量。
  • 初始化left为0,表示使用0个光盘;right为files.length + 1,表示使用files.length + 1个光盘(最坏情况);
  • 当left < right时,进行二分查找:
    • 计算mid为(left + right) / 2。
    • 调用cal方法判断是否可以将所有文件分布在mid个光盘中。
      • 在cal方法中,创建长度为mid的整数数组nums,用于记录每个光盘的剩余容量,初始值为500MB;
      • 从文件大小数组files的末尾开始遍历文件大小:
        - 对nums数组进行升序排序,以便从剩余容量最大的光盘开始分配;
        - 如果剩余容量最大的光盘可以容纳当前文件大小f,则将该文件分配给该光盘,并更新光盘的剩余容量;
        - 如果剩余容量最大的光盘无法容纳当前文件大小f,则返回false,表示无法将所有文件分布在当前的光盘数量中;
        - 如果能够将所有文件分布在当前的光盘数量中,则返回true。
        - 如果cal方法返回true,表示当前的光盘数量可以容纳所有文件,将right更新为mid。
        - 如果cal方法返回false,表示当前的光盘数量无法容纳所有文件,将left更新为mid + 1。
  1. 输出最终确定的光盘数量left。

解题思路分析:

该算法使用二分查找的思想确定最少的光盘数量。首先对文件的大小进行升序排序,然后在二分查找的过程中,通过调用cal方法判断当前的光盘数量是否可以容纳所有文件。在cal方法中,根据剩余容量最大的光盘逐个分配文件,并更新光盘的剩余容量。通过不断调整二分查找的左右边界,最终确定最少的光盘数量。算法的时间复杂度为O(log n),其中n为文件数量。

五、Java算法源码

public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    // 每组文件大小的数据
    int[] files = Arrays.stream(in.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
    // 对文件的大小进行升序排序
    Arrays.sort(files);
    int left = 0;
    int right = files.length + 1;

    while (left < right) {
        int mid = (left + right) / 2;
        // 如果方的下,向左移动
        if (cal(mid, files)) {
            right = mid;
        } else {// 如果放不下,向右移动
            left = mid + 1;
        }
    }
    System.out.println(left);
}

/**
 * 是否放的下
 * @param mid 中间节点
 * @param files 每组文件大小的数据
 */
public static boolean cal(int mid, int[] files) {
    int[] nums = new int[mid];
    for (int i = 0; i < mid; i++) {
        nums[i] = 500;
    }

    for (int i = files.length - 1; i >= 0; i--) {
        int f = files[i];
        Arrays.sort(nums);
        if (nums[mid - 1] >= f) {
            nums[mid - 1] -= f;
        } else {
            return false;
        }
    }

    return true;
}

六、效果展示

1、输入

100 200 300 400 500

2、输出

3

3、说明

100 + 400、200 + 300 、500 三张光盘即可。

华为OD机试 - 数据最节约的备份方法 - 二分查找(Java 2023 B卷 100分)_第1张图片


下一篇:华为OD机试真题 Java 实现【简易内存池】【2023 B卷 200分 考生抽中题】

本文收录于,华为OD机试(JAVA)真题(A卷+B卷)

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述

你可能感兴趣的:(搬砖工逆袭Java架构师,华为od,java,二分查找,学习)