http://acm.hdu.edu.cn/showproblem.php?pid=1969
自己纠结了很久,然后参考别人代码才知道,要学以致用啊!
http://www.cnblogs.com/newpanderking/archive/2011/08/24/2152576.html
题目大意是要办生日Party,有n个馅饼,有f个朋友,接下来是n个馅饼的半径。然后是分馅饼了, 注意咯自己也要,大家都要一样大,形状没什么要求,但都要是一整块的那种,也就是说不能从两个饼中 各割一小块来凑一块,像面积为10的和6的两块饼(饼的厚度是1,所以面积和体积相等), 如果每人分到面积为5,则10分两块,6切成5,够分3个人,如果每人6,则只能分两个了! 题目要求我们分到的饼尽可能的大!
只要注意精度问题就可以了,一般WA 都是精度问题
运用2分搜索:
首先用总饼的体积除以总人数,得到每个人最大可以得到的V,但是每个人手中不能有两片或多片拼成的一块饼,
最多只能有一片分割过得饼。用2分搜索时,把0设为left,把V 设为right。mid=(left+right)/2;
搜索条件是:以mid为标志,如果每块饼都可以分割出一个mid,那么返回true,说明每个人可以得到的饼的体积可以
大于等于mid;如果不能分出这么多的mid,那么返回false,说明每个人可以得到饼的体积小于等于mid。
(1)精度为:0.000001
(2) pi 用反余弦求出,精度更高。
#include<iostream>
#include<math.h>
#include<iomanip>
using namespace std;
double pi=acos(-1.0);
double v[10001];
double mid;
int f,n;
bool test(double x)
{
int i;
int num=0;
for(i=0;i<n;i++)
{
num+=(int )(v[i]/x);
}
if(num>=f) return true;
else return false;
}
int main()
{
int t;
cin>>t;
while(t--)
{
int i,r;
double V=0,start,end;
cin>>n>>f;
f=f+1;
for(i=0;i<n;i++)
{
cin>>r;
v[i]=pi*r*r;
V+=v[i];
}
// cout<<f<<endl;
V=V/f;
start=0.0;
end=V;
while((end-start)>1e-6)
{
mid=(start+end)/2;
if(test(mid))
start=mid;
else end=mid;
}
cout<<setiosflags(ios::fixed)<<setprecision(4)<<mid<<endl;
}
return 0;
}