问题描述
有N根绳子,第i根长为Li,现需要m根等长绳子。你可以对n根绳子进行任意剪裁(不能拼接),计算出这m根绳子最长的长度多少?
输入描述:
第一行包括两个整数N,M,含义如题所述(1 <= N,M <= 100000)
第二行包含N个整数,分别对应N根绳子的长度(0 < l[i] < 10^9)
输出描述:
一个数字,表示裁剪后最长的长度,保留两位小数
示例1
输入:
3 4
3 5 4
输出:
2.50
解释: 第一根和第三根绳子分别裁剪出一根2.50长度的绳子,第二根绳子刚好可以裁剪出两根2.50的长度绳子,刚好4根。
解题思路
裁剪后每根绳子的长度肯定是在0到Max(原来绳子的长度)之间,要求出这个长度需要用二分查找法来找
解题代码
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//现有绳子的数量为n
int n = sc.nextInt();
//需要剪成m根绳子
int m = sc.nextInt();
//现在每根绳子的长度
int[] length = new int[n];
for(int i = 0;i < n;i++){
length[i] = sc.nextInt();
}
//找到最长的那根绳子,截取后每根绳子的长度不可能大于它
int max = length[0];
for (int i = 1; i < n; i++) {
if (max < length[i]) max = length[i];
}
//二分查找法
double high = max;
double low = 0;
double mid = 0;
//计算按照最大长度裁剪得到的绳子根数
int count ;
//1.0E-6是运算的精度
while (high - low > 1.0E-6){
mid = (low + high) / 2;
count = checkMax(length, mid);
//如果计算出的结果小于m,说明最大长度大了,
if (count < m)
high = mid;
//如果计算出的结果大于m,说明最大长度小了,
else
low = mid;
}
System.out.println(String.format("%.2f",mid));
}
private static int checkMax(int[] a, double maxLength) {
int count = 0;
for (int i = 0; i < a.length; i++) {
Double s = a[i] / maxLength;
int s1 = s.intValue();
count += s1;
}
return count;
}
}