分配派问题题目大意:
我要过生日了,准备了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 }