分配派问题题目大意

我要过生日了,准备了n个不同半径大小的圆形的pie,我有f 个朋友要来参加我的聚会,我要将pie公平分配,且给每人(包括我自己)分配一块尽量大的pie。(因为碎块看起来不上台面。)求分配每个人的pie的体积的最大值。(pie的厚度一定,等于1)

分析

运用二分法:将每个人能分配到的pie最大体积区间一直二分,直到不满足条件:while(left+0.0001<right)。   体积区间为[left,right]。

Input:
One line with a positive integer: the number of test cases. Then for each test case:
• One line with two integers N and F with 1 ≤ N, F ≤ 10000: the number of pies and the number
of friends.
• One line with N integers ri with 1 ≤ ri ≤ 10000: the radii of the pies.


Output:
For each test case, output one line with the largest possible volume V such that me and my friends can
all get a pie piece of size V . The answer should be given as a oating point number with an absolute
error of at most 10−3。


案例输入输出:

Sample Input:
3
3 3
4 3 3
1 24
5
10 5
1 4 2 3 4 5 6 5 4 2

Sample Output:
25.1327
3.1416
50.2655

代码及步骤分析:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 using namespace std;
 5 const int m=10005;
 6 double p[m];
 7 const double pi=acos(-1);
 8 double max(double x,double y)
 9 {
10     if(x>=y)
11         return x;
12     else
13         return y;
14 }
15  
16 int main()
17 {
18     int t;
19     scanf("%d",&t);
20     while(t--)
21     {
22         int n,f,c,i;
23         double sum=0, maxn=0;
24         scanf("%d%d",&n,&f);
25         f=f+1;            //   人数需加上主人自己
26         for(i=0;i<n;i++)
27         {
28           scanf("%d",&c);
29           p[i]=pi*c*c;   // p[i]每块派的体积
30           maxn=max(maxn,p[i]);   //保存所有派体积最大值
31           sum+=p[i];       //所有派的体积和
32         }
33         
34         double left=maxn/f;     //每人能分配到的派的最大体积的区间为[left,right]
35         double right=sum/f;
36         
37         double mid;
38         while(left+0.0001<right)   //当这个区间趋近0时停止循环得到结果。此0.0001不可省略。因为精度要求为0.0001,
39         {                           //所以只有当误差大小left-right<0.0001时才可退出迭代得到结果
40             int cnt=0;             //cnt必须在循环内部置0!!!
41             mid=(left+right)/2;
42             for(i=0;i<n;i++)
43                 cnt+=floor(p[i]/mid);
44             if(cnt<f)   //注意区间的改变
45                 right=mid;
46             else
47                 left=mid;
48             
49         }
50         printf("%.4lf\n",left);
51     }
52     return 0;
53 }

 

posted on 2015-08-08 17:35  xx-sisley  阅读(219)  评论(0编辑  收藏  举报