import java.io.*;
import java.util.Arrays;
/**
* 编码能力提升
* 选中n道题,计划在m天刷完
* 不能多天刷一题
* 可以直接看答案,省去做题时间
* 每天最多看一次答案
* 定义m天中做题时间最多的一天耗时为T(直接看答案的题目不计入做题时间)
* 求最小的T
*/
public class EncodingCapabilityEnhancementPlan {
/**
* times[i]的时间完成编号i的题目
*/
private static int[] times;
/**
* 完成所有题目的天数限制
*/
private static int daysLimit;
/*
999,998,997
1
-------------------
1995
+++++++++++++++++++
999,998,997
2
-------------------
997
+++++++++++++++++++
999,998,997
3
-------------------
0
*/
private static String line;
private static String[] strArr;
private static int length;
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;
//将题目由易到难排序
times = Arrays.stream(strArr).mapToInt(Integer::parseInt).sorted().toArray();
//记录限制天数
line = in.readLine();
daysLimit = Integer.parseInt(line);
//关闭接收器
in.close();
out.println(encodingCapabilityEnhancementPlan());
out.flush();
out.close();
}
/**
* 二分法计算在限定天数内的最小T
* @return 最小的T
*/
public static int encodingCapabilityEnhancementPlan(){
int result = -1;
//做题时间最多的一天所花的最短时间(一天只做一道,且直接看答案)
int low = 0;
//做题时间最多的一天所花的最长时间(所有题一天做完,最难的一道看答案)
int high = Arrays.stream(times).sum() - Arrays.stream(times).max().orElse(0);
//二分法求在限定天数内的最小T
while (low <= high) {
int mid = low + (high - low) / 2;
if (isFeasible(mid)) {
result = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
return result;
}
/**
* 判断能否在规定时间内做完题
* 不能多天完成同一题
* 一天只能看一次答案
* @param timeLimit 做题时间最多的一天所花的时间
* @return 能否在规定时间内做完题
*/
private static boolean isFeasible(int timeLimit) {
//今天已经花了多少时间
int currentDayTime = 0;
//是否可以看答案
boolean canSeeAnswer = true;
//今天是做题第几天
int currentDay = 1;
//题号
int i = 0;
//循环刷题
while (i < length) {
//做完当前题,不超过时间限制
if (currentDayTime + times[i] <= timeLimit) {
//把这道题做完
currentDayTime += times[i];
//做下一题
i++;
} else {//已经没有时间做这道题
if (canSeeAnswer) {//还可以看答案
//直接看答案
canSeeAnswer = false;
//做下一题
i++;
} else {//不能看答案了
//时间切换到第二天
currentDay++;
//当天时间初始化
currentDayTime = 0;
//答案标记初始化
canSeeAnswer = true;
}
}
}
//所花费时间是否超过天数限制
return currentDay <= daysLimit;
}
}
【二分法】编码能力提升
于 2024-03-28 09:06:16 首次发布
本文介绍了一个Java程序,通过二分法计算在给定天数限制下,完成一系列按难度排序的题目,使得在最多一天内花费的做题时间最小,同时满足每天只能做一道题且最多看一次答案的要求。
摘要由CSDN通过智能技术生成