1. 程式人生 > >切繩子

切繩子

題目描述

有n條繩子,長度分別為L[i]。如果從他們中切割出k條長度相同的繩子的話,這k條繩子每條最長能有多長?(答案保留小數點後兩位,規定1單位長度的繩子最多可以切割成100份)

輸入

輸入n,k,(1<=n,k<=10000)

然後n行,輸入L[i],代表每一條繩子的長度(1<=L[i]<=100000)

輸出

切出k條長度相等的繩子最大長度是多少,輸出保留兩位小數

樣例輸入

4 11
8.02
7.43
4.57
5.39

樣例輸出

2.00

分析:

本題的基本思路。我們可以運用二分查詢法。我們可以用二分查詢,查詢到一個數,將其中每條繩子與之相除得到能剪成多少根繩子。算出總的繩子數。然後,比較判斷。如果繩子數大於等於需要的繩子數,那麼我們可以繼續二分,不過將起點改成之前的中點(即上次的查詢長度)。如果,繩子數小於需要的繩子數,我們繼續二分,不過將其終點改成上次查詢的中點。繼續查詢。

#include"stdio.h"
#include"string.h"

double Serch(double Rope[],long long k,long long N)
{
    long long i,j=0;
    long long count=0;
    //這裡的Min_leght賦值成一個很大的數;
    //之所以不用最小的那個繩子的長度。是因為有可能不需要對最小繩子進行操作。
    //即其他繩子能夠剪出長度大於最小繩子的長度的可能性。
    //所以Min_leght=1000000.0而不是最小繩子的長度。
    double Min_leght=1000000.0,Mid_leght=Rope[0]/2,end_leght,strat_leght=0;
    //這裡的精度極高,而且易出錯,推薦直接執行100次迴圈就好了,就可以不用考慮精度
    while(Min_leght-strat_leght>=0.00000000000002)
    {  Mid_leght=(Min_leght+strat_leght)/2;
        for(i=0;i<N;i++)
        {
            count+=(long long)(Rope[i]/Mid_leght);
        }
        if(count>=k)
            strat_leght=Mid_leght;
        else
            Min_leght=Mid_leght;
       // printf("count=%lld\n",count);
        count=0;
    }
  return Mid_leght;
}
int main()
{
    long long n,k;
    double Rope[10001],T,leght;
    long long i,j,count;
    while(~scanf("%lld%lld",&n,&k))
    {
        for(i=0;i<n;i++)
            scanf("%lf",&Rope[i]);

        leght=Serch(Rope,k,n);
        printf("%0.2lf\n",(long long )(leght*100)/100.0);

    }
}