1、题目描述
有N根绳子,第i根绳子长度为LiLi,现在需要M根等长的绳子,你可以对N根绳子进行任意裁剪(不能拼接),请你帮忙计算出这M根绳子最长的长度是多少。
输入格式
第一行包含2个正整数N、M,表示原始绳子的数量和需求绳子的数量。
第二行包含N个整数,其中第 i 个整数LiLi表示第 i 根绳子的长度。
输出格式
输出一个数字,表示裁剪后最长的长度,保留两位小数。
数据范围
1≤N,M≤1000001≤N,M≤100000,
0<Li<1090<Li<109输入样例:
3 4 3 5 4
输出样例:
2.50
样例解释
第一根和第三根分别裁剪出一根2.50长度的绳子,第二根剪成2根2.50长度的绳子,刚好4根。
2、分析
使用二分
浮点数二分模板:
bool check(double x) {/* ... */} // 检查x是否满足某种性质
double bsearch_3(double l, double r)
{
const double eps = 1e-6; // eps 表示精度,取决于题目对精度的要求
while (r - l > eps)
{
double mid = (l + r) / 2;
if (check(mid)) r = mid;
else l = mid;
}
return l;
}
3、代码
import java.io.*;
import java.util.*;
public class Main{
static int N = (int)1e5 + 10;
static int[] len = new int[N];
static int n, m;
static boolean check(double length) {
int s = 0;
for(int i = 0;i < n;i ++) {
s += len[i] / length;
if(s >= m) return true;
}
return false;
}
public static void main(String[] args) {
Scanner in = new Scanner(new InputStreamReader(System.in));
n = in.nextInt(); //原始绳子数
m = in.nextInt(); //目标数量
for(int i = 0;i < n;i ++) {
len[i] = in.nextInt(); //每根绳子的长度
}
//浮点数二分
double l = 0, r = 1e9;
while(r - l > 1e-4) {
double mid = (l + r) / 2;
if(check(mid)) {
l = mid;
}else {
r = mid;
}
}
System.out.println(String.format("%.2f", l));
}
}