Pie(分蛋糕问题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1969

题意:

      多组案例。办生日Party,有N个馅饼,有F个朋友,接下来是N个馅饼的半径。然后是分馅饼,注意每个人都要一样大,形状没什么要求,但都要是一整块的,也就是说不能从两个饼中割一小块来凑一块。饼的厚度一致可看为1,所以面积和体积相等。打比方说,面积为10的和6的两块饼,如果每人分到面积为5,则10分两块,6切成5,够分3个人,如果每人6,则只能分2个了!题目要求每人分到的饼尽可能的大!

案例:

        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
分析:

       该题跟我刚完成的抄书问题类似,均采用二分法查找。所需注意的是精度的设定,left和right要尽可能靠近,我初始将精度设定为十的负八次方,可惜的是超时,后改为负六次方才通过。还有要注意的是分蛋糕的人应包括自己在内,即有F+1个人分蛋糕,而且蛋糕切的块数许多不许少,要让每人分到的蛋糕面积尽可能大,就尽量避免浪费,蛋糕切分块数尽可能靠近要分的人数。另外,pi 用反余弦求出,精度更高。

源代码:

 1 #include<cstdio>
 2 #include<cmath>
 3 int T,N,F;
 4 double a[10005],r,left,right,mid;
 5 double pi=acos(-1.0);//pi值确定
 6 bool check(double max)
 7 {
 8     int j,tot=0;
 9     for(j=1;j<=N;j++)
10         tot+=int(a[j]/max);//每人分max面积的蛋糕,计算所有蛋糕能分总数
11     if(tot>=F+1)//判断能否每人一块,许多不许少
12         return true;
13     else
14         return false;
15 }
16 int main()
17 {
18     int i;
19     scanf("%d",&T);//案例数
20     while(T--)
21     {
22         scanf("%d%d",&N,&F);//蛋糕数N和人数F
23         for(i=1;i<=N;i++)
24         {
25             scanf("%lf",&r);//单块蛋糕半径
26             a[i]=pi*r*r;//单块蛋糕面积
27             right+=a[i];//计算所有蛋糕总面积
28         }
29         left=0.0;//分配蛋糕最小面积极限
30         right=right/(F+1);//分配蛋糕最大面积极限
31         while((right-left)>1e-6)//二分法精度判定
32         {
33             mid=(left+right)/2.0;
34             if(check(mid))
35                 left=mid;
36             else right=mid;
37         }
38         printf("%.4lf
",mid);//最终结果
39     }
40     return 0;
41 }
原文地址:https://www.cnblogs.com/huaszjh/p/4705785.html