题目描述
问题链接https://www.acwing.com/problem/content/description/682/
分析
我们可以将最优解的问题转换为判断是否满足条件问题的话会大大降低题目的难度。
- 这道题的关键思路是二分查找
- 通过循环找最大值赋值给right,因为特殊性,我们最小值left只能从0开始。
- 然后开始二分查找,查找的过程中进行判断,如果每条绳子除以mid之后的和大于等于m,则left=mid;如果和小于mid,则right=mid;,否则即满足要求返回left或right
下面结合题目的数据来简单分析一下
AC代码
import java.util.*;
public class Main{
public static void main(String[] args)
{
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
int m=scan.nextInt();
int[] arr=new int[n+1];
int max = 0;
for(int i=0;i<n;i++)
{
arr[i]=scan.nextInt();
max = Math.max(max, arr[i]);
}
double left=0;
double right=max;
//题目要求精度为两位小数所以取0.001
while(Math.abs(right-left)>0.001) {
double mid = (left + right) / 2;
int count=0;
for(int i=0;i<n;i++)
{
count+=(int)arr[i]/mid;
}
if (count>=m) {
left = mid;
} else {
right = mid;
}
}
System.out.printf("%.2f\n",right);
}
}