题目
大概题目如下
有N根绳子,第i根长为Li,现需要m根等长绳子。
对n根绳子进行任意剪裁(不能拼接),计算出这m根绳子最长的长度
思路
既然是要得出裁剪后的绳子长度,那么 绳子长度是一定小于或等于 最长的绳子
(注意不是最短的绳子,如果最短的绳子和最长的绳子差距太大,舍去最短绳子一样能够 满足 m根的要求 而且都比 最短的绳子长)
且一定大于 0
要在(0,max )中找到一个 l 使 用它剪出的绳子 为 m 根
genius 的你,已经知道了,要使用 二分查找 ~~yabei
定义一个check函数 ,判断 长度为l的绳子 可以剪出多少根,返回res 代表
如果res > m,说明也许还能更长(~~sigei),即下限提高 , 按照二分查找的原理,此时的min= (max+min)/2
同理 res<m ,说明太长了,要将上限降低 max=mid;
(这样的话答案就只有一个了)
代码
public class test{
public static void main(String args[]) {
int m;//给定的根数
int num ;//总的绳子数
int nums[];//每根绳子的长度
//最大的裁剪长度 必须小于 max,大于min 使用二分查找
m=4;
num =3;
nums =new int [m];
nums[0]=3;
nums[1]=5;
nums[2]=4;
solution s =new solution ();
s.so(nums, num, m);
}
}
class solution {
public void so(int [] nums,int num,int m) {//nums[] 每根的长度,num 根数,m要求的根数
double max =999;
double min =0;
for(int i=0;i<num;i++) {
if(max>nums[i]) {
max=nums[i];
}
}
//
double exp =0.1;
double mid = 0 ;
while(max-min>=exp) {
mid =(max+min)/2;
if(m>check(nums,mid)) {
//l长了,将max改小
max=mid;
continue;
}
else {
min=mid;
continue;
}
}
System.out.println(mid );
}
int check(int[] nums,double mid)//返回能够减出的最多条数,如果比要求的大,说明 l长了 ,反之则小了
{
int res=0;
;
for(int i=0;i<nums.length;i++) {
res=(int) (res+(int)nums[i]/mid);
}
System.out.println("现在的 l长度为 "+ mid+" 可以得到的条数为"+res);
return res;
}
}