最短木板长度
题目描述:
小明有 n 块木板,第 i ( 1 ≤ i ≤ n ) 块木板长度为 ai。
小明买了一块长度为 m 的木料,这块木料可以切割成任意块,
拼接到已有的木板上,用来加长木板。
小明想让最短的木板尽量长。
请问小明加长木板后,最短木板的长度可以为多少?
输入输出描述:
输入描述:
输入的第一行包含两个正整数,n(1≤n≤103),m(1≤m≤106)
n表示木板数,m表示木板长度。输入的第二行包含n个正整数,a1,a2,…an(1≤ai≤10^6)。
输出描述:
输出的唯一一行包含一个正整数,表示加长木板后,最短木板的长度最大可以为多少?
示例1:
输入:
5 3
4 5 3 5 5
输出:
5
说明:
给第1块木板长度增加1,给第3块木板长度增加2后,
这5块木板长度变为[5,5,5,5,5],最短的木板的长度最大为5。
示例二:
输入:
5 2
4 5 3 5 5
输出:
4
说明:
给第3块木板长度增加1后,
这5块木板长度变为[4,5,4,5,5],剩余的木料长度为1。
此时剩余木料无论给哪块木板加长,最短木料的长度都为4。
解题思路:
谈心策越:
分2种情况:
1、如果所有木板长度一样,就把木料的均分都每一块木板上
2、如果所有木板长度不一样,就排序,计算出第一短和第二短的木板的长度差,将木料都先不再第一短的所有木板上。如果木料长度不够将所有最短的木板长度调整为第二短,那么可直接结束循环。如果木料还有剩余,则继续按照这两种情况循环继续分割木料。
代码:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String[] split = scanner.nextLine().split(" ");
int n = Integer.parseInt(split[0]);
int m = Integer.parseInt(split[1]);
int[] nums = new int[n];
//处理输入
split = scanner.nextLine().split(" ");
for (int i = 0; i < n; i++) {
nums[i] = Integer.parseInt(split[i]);
}
if (n == 1) {
System.out.println(nums[0] + m);
return;
}
while (m > 0) {
// 排序
Arrays.sort(nums);
// 给最短的木板数量
int index = 1;
while (index < n && nums[index - 1] == nums[index]) {
index++;
}
// 如果长度都一样,把 m 均分,接在每一块板子上
if (index == n) {
System.out.println(m / n + nums[0]);
return;
} else {
// 最短和第二短之间相差多少米
int diff = nums[index] - nums[index - 1];
if (index * diff <= m) {
// 让最短和第二短的木板长度一致
m -= index * diff;
while (index > 0) {
nums[--index] += diff;
}
} else {
// m 长度不足以让最短和第二短的木板长度一致
System.out.println(nums[0] + m / index);
return;
}
}
}
System.out.println(nums[0]);
}