蓝桥双周赛第二十七场蓝桥月赛最后一题 备份比赛数据 题解
「蓝桥·算法双周赛」第二十七场蓝桥月赛最后一题题解
(可能是首发??nm,真比第三题简单吧)
(求你们看看吧我对我的码风很自信)
问题描述
题面
是一道很美丽的二分题
二分枚举时间m,然后剩下的就是根据题意纯模拟
注意备份和等待能不能跨天进行,这是个坑点
细节在注释里有
package 蓝桥月赛第27场;
import java.util.Scanner;
public class F {
private static int calculateDays(int m, int[] a, int[] b) {
// 如果没有电脑需要备份,返回 0 天
if(a.length == 0) return 0;
// 如果 M 小于第一台电脑的备份时间
if(m < a[0]) return Integer.MAX_VALUE;
// 第一天
int days = 1;
// 备份第一台开始算剩余时间
int currentRemaining = m - a[0];
// 第一台都备份不上??
if (currentRemaining < 0) {
return Integer.MAX_VALUE;
}
for (int i = 1; i <= a.length; i++) {
int wait = b[i]; // 获取前一台电脑的等待时间
// 处理等待时间
// 时间足够,直接减去
if(currentRemaining >= wait) {
currentRemaining -= wait;
// 不够只能过天了,计算剩余的等待时间
}else {
// 把当天能等的给等了
wait -= currentRemaining;
days++;
currentRemaining = m; // 重置剩余时间
int fullDays = wait / m; // 计算等几天
days += fullDays;
wait -= fullDays * m;
if(wait > 0) {
// 减去零头
currentRemaining = m - wait;
}else {
currentRemaining = m; // 重置
}
}
// 处理备份时间
// 今天够备份
if(currentRemaining >= a[i]) {
currentRemaining -= a[i];
}else {
// 今天备份不完,备份不能留到第二天
days++;
currentRemaining = m - a[i];
// 不行,时间太短,备份不完
if (currentRemaining < 0) {
return Integer.MAX_VALUE;
}
}
}
return days;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// N 台电脑
int n = scanner.nextInt();
// 最多允许的天数T
int t = scanner.nextInt();
// 表示每台电脑的备份时间。
int[] a = new int[n];
for (int i = 1; i <= n; i++) {
a[i] = scanner.nextInt();
}
// 每台电脑备份完成后需要等待的时间。
int[] b = new int[n];
for (int i = 1; i <= n; i++) {
b[i] = scanner.nextInt();
}
scanner.close();
// 最长备份时间
int maxA = 0;
for(int ai: a) {
if (ai > maxA) {
maxA = ai;
}
}
if (maxA > 3600) {
System.out.println(-1);
return;
}
// 开始二分 枚举m
int left = maxA;
int right = 3600;
int result = -1;
while(left <= right) {
int mid = (left + right) / 2;
int days = calculateDays(mid, a, b);
if (days <= t) {
result = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
System.out.println(result != -1 ? result : -1);
}
}