有 N 根绳子,第 i根绳子长度为 Li,现在需要 M 根等长的绳子,你可以对 N 根绳子进行任意裁剪(不能拼接),请你帮忙计算出这 M 根绳子最长的长度是多少。
输入格式
第一行包含 2 个正整数 N, M,表示原始绳子的数量和需求绳子的数量。
第二行包含 N个整数,其中第 i 个整数 Li 表示第 i 根绳子的长度。
输出格式
输出一个数字,表示裁剪后最长的长度,保留两位小数。
这道题运用了二分法
二分查找/折半查找
前提条件:数组中的数据必须是有序的
核心逻辑:每次排除一半的查找范围
1、min和max表示当前要查找的范围
2、mid是在min和max的中间
3、如果要查找的元素在mid的左边,缩小范围时,min不变,max等于mid减1
4、如果要查找的元素在mid的右边,缩小范围时,max不变,min等于mid加1
import java.util.Arrays; import java.util.Scanner; public class Java35 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(),m = sc.nextInt(); int[] arr = new int[1000000]; for (int i = 0; i < n; i++) { arr[i] = sc.nextInt(); } Arrays.sort(arr,1,n); double sum = binarySearch(arr,arr[n-1],m); System.out.println(String.format("%.2f", sum)); } public static double binarySearch(int[] arr,double len,int m){ double right = len; double left = 0; while (right-left>1e-7){ double mid = (right+left)/2; int s = 0; for (int i = 0; i < arr.length; i++) { s = s +(int)(arr[i]/mid); } if (s>=m){ left = mid; } if (s<m){ right = mid; } } return left; } }