派(二分答案)


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 }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM