一、题目链接
http://noi.openjudge.cn/ch0109/15/
二、解题思路
三、实施步骤
四、Java程序
import java.util.Arrays;
import java.util.Scanner;
public class Main {
/**
* 返回给定数组中的最大值
*
* @param nums int类型的数组,代表给定数组
* @return int类型的整数,代表nums中的最大值
*/
public int max(int[] nums) {
int ans = nums[0]; // 初始时假定nums数组的第一个元素为最大值
/* 从nums数组的第二个元素开始,到最后一个元素为止 */
for (int i = 1; i < nums.length; i++) {
ans = (nums[i] > ans ? nums[i] : ans); // 如果当前元素nums[i]大于ans,将ans更新为nums[i]
}
return ans;
}
/**
* 返回给定数组中的最小值
*
* @param nums int类型的数组,代表给定数组
* @return int类型的整数,代表nums中的最小值
*/
public int min(int[] nums) {
int ans = nums[0]; // 初始时假定nums数组的第一个元素为最小值
/* 从nums数组的第二个元素开始,到最后一个元素为止 */
for (int i = 1; i < nums.length; i++) {
ans = (nums[i] < ans ? nums[i] : ans); // 如果当前元素nums[i]小于ans,将ans更新为nums[i]
}
return ans;
}
/**
* 计算所有同学都接完水需要的时间
*
* @param water int类型的数组,存储每个同学的接水量
* @param m int类型的整数,代表水龙头的数量
* @return int类型的整数,代表所有同学都接完水需要的时间
*/
public int time(int[] water, int m) {
int n = water.length; // 同学的人数
// 存储m个水龙头当前的接水情况,初始时为前m个同学的接水量
int[] faucets = Arrays.copyOfRange(water, 0, m);
int ans = 0; // 所有同学都接完水需要的时间,初始时为0
int minWater; // m个水龙头当前接水过程中最小的接水量
int k = m; // 当前排队的队首同学编号,初始时为m
LoopWhile:
/* 在排队同学尚未全部排完时 */
while (k < n) {
minWater = min(faucets); // 获得m个水龙头当前接水过程中的最小接水量
ans = ans + minWater; // 将minWater所需时间累加到ans上
/* 遍历m个水龙头 */
for (int j = 0; j < m; j++) {
if (faucets[j] > minWater) { // 如果当前水龙头接水量大于minWater
faucets[j] = faucets[j] - minWater; // 减去minWater所需时间
}
else { // 否则,当前水龙头接水量等于minWater
if (k == n) { // 如果此时排队已经结束
break LoopWhile; // 跳出循环过程
}
faucets[j] = water[k]; // 排队队首同学开始接水
k++; // 下一个同学排到队首
}
}
}
ans = ans + max(faucets); // 排队接水过程结束后,累加剩余接水同学中最大接水量所需时间
return ans;
}
public static void main(String[] args) {
Main test = new Main();
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int m = input.nextInt();
int[] water = new int[n];
for (int i = 0; i < n; i++) {
water[i] = input.nextInt();
}
System.out.print(test.time(water, m));
}
}