思路
下载行为是怎么运作的: 0时刻 速度1 1 2 时间5 3 1 1时刻(执行1秒后) 5-1=4 3-1=2 1-2=-1 任务3执行完毕 分配给任务3的速度 现在要分配给任务1,任务2 分配方法 任务3速度/未完成任务数 = 每个未完成任务分到的速度 2/2=1 修改 任务1,任务2的速度 1+1=2 1+1=2 速度 2 2 时间 4 2 2时刻(执行1秒后) 4-2=2 2-2=0 任务2执行完毕 如上 2/1=2 2+2=4 修改任务1速度 速度 4 时间 2 当前只剩下一个任务 时间/速度 = 2/4 = 0.5 总运行时间 = 1+1+0.5=2.5
解法
class Solution {
public double method(List list1, List list2) {
//总运行时间
double sum = 0;
//循环条件为 是否还有未执行完的任务
while (list2.size() != 0) {
//当只剩一个任务时 任务剩余时间/速度 = 最后一个任务执行需要的时间
//将其 加到 运行总时间中 结束循环
if (list2.size() == 1) {
sum += list2.get(0) / list1.get(0);
break;
}
//当任务数 > 1 时 定义 每一轮while循环 sum+1
else {
sum += 1;
}
double v = 0;
List l1 = new ArrayList<>();
List l2 = new ArrayList<>();
for (int i = 0; i < list2.size(); i++) {
//某任务 执行1s后 剩余的执行时间
double time = list2.get(i) - list1.get(i);
//time <=0 该任务执行完毕 收回分配的速度
if (time <= 0) {
//拿到 1s 执行后 多余出来的 速度v
v += list1.get(i);
//定义两个集合 分别放入要删除的速度和任务的下标
l1.add(i);
l2.add(i);
} else {
//修改 任务剩余时间
list2.set(i, list2.get(i) - list1.get(i));
}
}
//定义 c 来控制 元素下标的变化
int c = 0;
//删除 执行完的任务 删除的时机是每个任务都执行完1s的运行时间
while (l1.size() != 0) {
int x = l1.get(0);
int y = l2.get(0);
//删除 list1,list2中元素时 由于循环可能执行多次 即删除多个元素
//计算 被删除元素的下标
x = x - c;
y = y - c;
list1.remove(x);
list2.remove(y);
//移除l1,l2元素
l1.remove(0);
l2.remove(0);
c++;
}
//对 每个任务 执行速度 加速
for (int i = 0; i < list1.size(); i++) {
//某个完成的任务 之前的速度 / 当前未完成任务数 = 每个任务能分到的速度
double newV = v / list1.size();
//更新 每个未完成 任务的速度
list1.set(i, list1.get(i) + newV);
}
}
return sum;
}
}
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
//n 表示集合的元素数
int n = s.nextInt();
List list1 = new ArrayList<>();
List list2 = new ArrayList<>();
for (int i = 0; i < n; i++) {
list1.add((double) s.nextInt());
}
for (int i = 0; i < n; i++) {
list2.add((double) s.nextInt());
}
double d = method(list1, list2);
//保留小数点 后4位
System.out.printf("%.4fn", d);
}
}



