【HDUOJ】1961---Pie(二分)

来源:互联网 发布:mysql 查询语句 编辑:程序博客网 时间:2024/06/16 08:32

PieHDU - 1969

My birthday is coming up and traditionally I'm serving pie. Not just one pie, no, I have a number N of them, of various tastes and of various sizes. F of my friends are coming to my party and each of them gets a piece of pie. This should be one piece of one pie, not several small pieces since that looks messy. This piece can be one whole pie though. 

My friends are very annoying and if one of them gets a bigger piece than the others, they start complaining. Therefore all of them should get equally sized (but not necessarily equally shaped) pieces, even if this leads to some pie getting spoiled (which is better than spoiling the party). Of course, I want a piece of pie for myself too, and that piece should also be of the same size. 

What is the largest possible piece size all of us can get? All the pies are cylindrical in shape and they all have the same height 1, but the radii of the pies can be different. 
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 <= 10 000: the number of pies and the number of friends. 
---One line with N integers ri with 1 <= ri <= 10 000: 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 floating point number with an absolute error of at most 10^(-3).
Sample Input
33 34 3 31 24510 51 4 2 3 4 5 6 5 4 2
Sample Output
25.13273.141650.2655
思路分析:

(1)题意:共f+1个人,n块大小不同的馅饼。每个人都要被分到一块完整的馅饼,而且每个人的馅饼大小一样,并且要尽可能最大,求馅饼的大小。

(2)分析:每个人的馅饼都是完整的,要保证都一样,要从原来的大馅饼中切下小块馅饼,能切出的小馅饼一共要有f+1块。

(3)关键:采用二分的思想找馅饼的大小。假设x为馅饼大小,那么如果能切够大于等于f+1块,就说明符合条件,但要使馅饼尽量大,就要再看看比x大的数据有没有符合条件的;当然如果x不能切够,就说明x较大,要找比它小的。馅饼的大小肯定要小于原馅饼最大的一块的大小吧(这里容易有一个误区,就是认为既然后来的馅饼是从原来馅饼中切出来的,那么所切得馅饼的大小肯定就小于原馅饼最小一块的大小,其实并不是这样,想想哦,当馅饼数目比人数多时,要使切得的馅饼最大,肯定不从小的里面切哟。所以要找的是最大的。)那么二分的区间左端点就是0咯,右端点就是原来最大的馅饼大小呀。对了,还有,要求的是体积,体积=底面积*高,高为1,所以直接用面积计算即可。

代码如下:

#include<cstdio>#include<cstring>#include<cmath>#define PI acos(-1.0)double a[10000+11];int n,f;bool Check(double x)//关键是这个子函数 {int num=0;for(int i=0;i<n;i++){num+=(int)(a[i]/x);//计算可以切出的大小为x的馅饼的个数 if(num>=f)//一旦满足num>=f说明x这个大小满足条件 ,就可以返回true return true;}return false;}int main(){int t;scanf("%d",&t);while(t--){scanf("%d%d",&n,&f);f++;double lb=0,ub=0;for(int i=0;i<n;i++){scanf("%lf",&a[i]);a[i]=PI*a[i]*a[i];if(a[i]>ub)ub=a[i];}while(ub-lb>1e-5)//划精度范围 {double mid=(lb+ub)/2.0;if(Check(mid))//因为要使切得的馅饼大小尽可能的大,所以当mid满足条件时,看比它大的有没有符合的 lb=mid;//所以就要找mid的 右侧部分,右侧部分的右端点不变,左端点变成了mid; elseub=mid;//mid不满足条件,找较小的,在左侧。左端点不变,右端点变成mid; }printf("%.4lf\n",lb);//四位小数 }return 0;}


 

原创粉丝点击