题目:
http://poj.org/problem?id=3122
题意:
F+1个人分N个派,派可以切分但是每个人只能得到一块派,每个人得到的派体积必须相同,问最大可分体积
思路:
二分+贪心,最大可分的体积为最大派的体积,最小可分为0,二分遍历即可
这道题比较坑的地方在于要注意PI的精度,虽然题目只要求到3位小数,但是PI使用3.1415926会出错,这种常数精度应该尽量取高
代码:
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<functional>
#include<iomanip>
//#pragma comment(linker, "/STACK:102400000,102400000")//C++
using namespace std;
const int MAXINT = 0x7fffffff;
const int MAXSIZE = 10000 + 5;
const double PI = 3.141592653589793238462643383279502884197169399;
int main(){
int total;
cin>>total;
double pie[MAXSIZE];
while (total--){
int n,f;
double high=0,low=0;
memset(pie,sizeof(pie),0);
cin>>n>>f;
for (int i=0;i<n;++i){
int a;
cin>>a;
pie[i]=a*a*PI;
if (high<pie[i]) high=pie[i];
}
//cout<<"low "<<low<<" high "<<high<<endl;
double ans;
while (fabs(high-low)>1e-5){
double mid=(high+low)/2;
//cout<<"low "<<low<<" high "<<high<<" mid "<<mid<<endl;
//cout<<fabs(high-low)<<endl;
//getchar();
int sum=0;
for (int i=0;i<n;++i){
sum+=(int)(pie[i]*1.0/mid);
}
if (sum>=f+1){
ans=mid;
low=mid;
}
else {
high=mid;
}
}
//cout<<setiosflags(ios::fixed);
//cout<<setprecision(4)<<ans<<endl;
printf("%.4lf\n",ans);
}
return 0;
}