05:派
- 總時間限制:
- 1000ms
- 內存限制:
- 65536kB
- 描述
-
我的生日要到了!根據習俗,我需要將一些派分給大家。我有N個不同口味、不同大小的派。有F個朋友會來參加我的派對,每個人會拿到一塊派(必須一個派的一塊,不能由幾個派的小塊拼成;可以是一整個派)。
我的朋友們都特別小氣,如果有人拿到更大的一塊,就會開始抱怨。因此所有人拿到的派是同樣大小的(但不需要是同樣形狀的),雖然這樣有些派會被浪費,但總比搞砸整個派對好。當然,我也要給自己留一塊,而這一塊也要和其他人的同樣大小。
請問我們每個人拿到的派最大是多少?每個派都是一個高為1,半徑不等的圓柱體。 - 輸入
-
第一行包含兩個正整數N和F,1 ≤ N, F ≤ 10 000,表示派的數量和朋友的數量。
第二行包含N個1到10000之間的整數,表示每個派的半徑。 - 輸出
- 輸出每個人能得到的最大的派的體積,精確到小數點后三位。
- 樣例輸入
-
3 3 4 3 3
- 樣例輸出
-
25.133
【思路】劉汝佳藍本上的題目
一開始我是沒想到用二分答案,雖然這些題都是二分答案類型的,(當你做一道題目時,你不能正在學什么就往什么方面考慮,你要想,用什么方法為什么用這個方法)但是沒有標志性的
最小值最大的問法。然后我看了看題解。。。。。。
介紹一下藍本的思路:每個人分最多分所有派里面積最大的,要么無限小(這是答案范圍);卡答案的條件就是能不能分得到,顯然是用二分答案的
所以 二分答案的題目 比較直接的問法 最小值最大 一看就是二分答案了,但是比較隱形的問法 首先要看看有這么幾個特點1 能確定答案范圍 2有卡答案的條件
orz
【代碼】1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<iomanip> 5 #include<cmath> 6 using namespace std; 7 const double pi=acos(-1.0);// acos(-1.0)就是求-1.0的反余弦,經計算,acos(-1.0) 的值就是圓周率 8 const int MAXX=100009; 9 double a[MAXX]; 10 bool ok(double); 11 int n,f; 12 int main() 13 { 14 int T; 15 double maxx=0; 16 scanf("%d",&T); 17 while(T--) 18 { 19 scanf("%d%d",&n,&f); 20 for(int i=0;i<n;i++) 21 { 22 int r; 23 scanf("%d",&r); 24 a[i]=pi*r*r;//每個派的面積 25 maxx=max(maxx,a[i]);//max函數里的變量類型相同 ,都是double 26 } 27 double l=0,r=maxx; 28 while(r-l>1e-5)//精確 二分答案的套路過程 29 { 30 double m=(l+r)/2; 31 if(ok(m))l=m;//擴大范圍,看看每個人能不能分到更多 32 else 33 r=m; 34 } 35 printf("%.3lf",l);//printf格式化輸出會自動四舍五入; 36 } 37 return 0; 38 } 39 bool ok(double s)//每人是否能分面積s的派 40 { 41 int sum=0; 42 for(int i=0;i<n;i++) 43 { 44 sum+=floor(a[i]/s);//向下取整,分不到s的浪費; 45 } 46 return sum>=f+1;//能否分到 47 }
-
