欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【每日一题】DAY6——剪绳子

程序员文章站 2022-07-12 21:53:48
...

题目

题目描述

N N N根绳子,第 i i i根绳子长度为 L i L_i Li,现在需要 M M M根等长的绳子,你可以对 N N N根绳子进行任意裁剪(不能拼接),请你帮忙计算出这M根绳子最长的长度是多少。

输入格式

第一行包含2个正整数 N N N M M M,表示原始绳子的数量和需求绳子的数量。

第二行包含 N N N个整数,其中第 i i i 个整数 L i L_i Li 表示第 i i i 根绳子的长度。

输出格式

输出一个数字,表示裁剪后最长的长度,保留两位小数。

数据范围

1 ≤ N , M ≤ 100000 1≤N,M≤100000 1N,M100000
0 < L i < 1 e 9 0<L_i<1e^9 0<Li<1e9

输入样例:

3 4
3 5 4

输出样例:

2.50

样例解释

第一根和第三根分别裁剪出一根2.50长度的绳子,第二根剪成2根2.50长度的绳子,刚好4根。

思路

这道题是一道典型的浮点数二分,关于二分的模版可以看线之前的代码模版:基础算法——常用代码模版

代码

import java.util.*;
import java.text.*;
class Main{
    public static int[] nums ;
    public static int n,m;
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
         n = sc.nextInt();
         m = sc.nextInt();
         nums = new int[n];
       for(int i = 0; i< n;i++){
           nums[i] = sc.nextInt();
       }
       sc.close();
       DecimalFormat df = new DecimalFormat("####.00");
       double l = 0.0;
       double r = 1e9;
       while( (r - l) > 0.0001){
           double mid = (l+r)/2;
           if(check(mid)) l = mid;
               else r= mid;
       }
       System.out.print(df.format(r));
    }
    public static boolean check(double length){
        int s= 0;
        for(int i = 0;i< n;i++){
            s+=(int) nums[i]/length;
            if(s >= m){
                return true;
            }
        }
        return false;
    }
}