切繩子
阿新 • • 發佈:2018-12-23
題目描述
有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); } }