【二分法】刻录光盘备份

import java.io.*;
import java.util.Arrays;

/**
 * 刻录光盘备份
 * 有一系列文件需要通过光盘备份。每张光盘的容量固定为500MB,文件的大小均为整数且不超过500MB
 * 文件不可拆分或分卷备份。需要确定最少需要多少张光盘来完成备份。
 */
public class BurnDiscBackup {
    /*
        100,500,300,200,400
        ------------------------
        3
        ++++++++++++++++++++++++
        100,100,200,300
        ------------------------
        2
     */
    private static String line;
    private static String[] strArr;
    private static int length;
    private static int[] fileSizeArr;
    private static int result;
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        line = in.readLine();
        strArr = line.split(",");
        length = strArr.length;
        //文件数组升序排列
        fileSizeArr = Arrays.stream(strArr).mapToInt(Integer::parseInt).sorted().toArray();

        burnDiscBackup();
        out.println(result);
        out.flush();
        in.close();
        out.close();
    }

    /**
     * 刻录光盘备份
     */
    public static void burnDiscBackup() {
        //最少需要一张光盘
        int low = 1;
        //最大需要数组长度张光盘
        int high = length;
        //二分查找能装下文件的最少光盘数
        while (low <= high) {
            int mid = low + (high - low) / 2;
            if (canFitFiles(mid)) {
                result = mid;
                high = mid - 1;
            } else {
                low = mid + 1;
            }
        }
    }

    /**
     * 判断磁盘是否装的下文件
     * @param discCount         光盘数量
     * @return                  是否能装下
     */
    private static boolean canFitFiles(int discCount) {
        //初始化光盘数组
        int[] discCapacities = new int[discCount];
        //每张光盘大小都是500
        Arrays.fill(discCapacities, 500);
        //从最大的文件开始存
        for (int i = length - 1; i >= 0; i--) {
            //磁盘容量升序排序
            Arrays.sort(discCapacities);
            //容量最大的磁盘装不下最大的文件,则判定装不下
            if (discCapacities[discCount - 1] < fileSizeArr[i]) {
                return false;
            }
            //能存下,则减去对应文件所占空间
            discCapacities[discCount - 1] -= fileSizeArr[i];
        }

        return true;
    }
}

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值