原题地址:
HDU-1969
题意解释:
有 F+1 个人分 N 个派吃,每个人吃的派必须体积相同,而且每个人只吃一块派,允许部分派被浪费。每个派是圆的,高度为1,半径由数据给出。
题目吐槽:
本来就是僧多粥少的分派吃,主人占据优势地位,要么大度点不吃,要么多吃点嘛,总想和客人吃相同大小的派,还非要发扬平均主义,每个人都吃体积一样的派。尤其是大家都有一个共同的癖好,都是不能接受食物碎屑的完美主义者,吃点剩下的能死啊。还有就是做派的师傅不走心,做出来的派大小不一,这派我要给差评!
解决方案:
二分搜索合适的分派方式
最小值是: 0 (大家都不吃)
最大值是:派的总体积 ÷ 总人数 (超完美平均主义)
每次取中间值 记作:mid,计算如果每个派切出 mid体积 能切多少块
如果能切够 F+1块,则将最小值更新为中间值
如果切不出 F+1块,则将最大值更新为中间值
直到两次中间值的差值 小于 10^(-4) 时就是结果了
如果评测不过。。。那就把精度调高一点吧
样例:
输入:
3
3 3
4 3 3
1 24
5
10 5
1 4 2 3 4 5 6 5 4 2
输出:
25.1327
3.1416
50.2655
然后贴上自己代码:
#include<iostream>
#include<vector>
#include<cmath>
#include<iomanip>
using namespace std;
const double PI=acos(-1.0);
double core(int n,vector<int> &TT){
double mmax=0,mmin=0,mid,dl=1;
for(unsigned int i=0;i!=TT.size();i++){
mmax+=TT[i]*TT[i]*PI;
}
mmax=mmax/n;
while(fabs(dl)>0.000001){
mid=(mmax+mmin)/2;
int num=0;
for(unsigned int i=0;i!=TT.size();i++){
num+=(int)((TT[i]*TT[i]*PI)/mid);
}
if(num<n){
mmax=mid;
}else{
mmin=mid;
}
dl=mmax-mmin;
}
return mid;
}
int main(){
int T;
cin>>T;
while(T--){
int n,f;
cin>>n>>f;
vector<int> T;
while(n--){
int val;
cin>>val;
T.push_back(val);
}
cout<<setiosflags(ios::fixed)<<setprecision(4)<<core(f+1,T)<<endl;
}
return 0;
}
//Designed by wolf