题目:蒜头君的生日要到了!根据习俗,他需要将一些派分给大家。他有 N个不同口味、不同大小的派。
有 F个朋友会来参加我的派对,每个人会拿到一块派(必须一个派的一块,不能由几个派的小块拼成;可以是一整个派)。我的朋友们都特别小气,如果有人拿到更大的一块,就会开始抱怨。因此所有人拿到的派是同样大小的(但不需要是同样形状的),虽然这样有些派会被浪费,但总比搞砸整个派对好。当然,我也要给自己留一块,而这一块也要和其他人的同样大小。
请问我们每个人拿到的派最大是多少?每个派都是一个高为1,半径不等的圆柱体。
输入格式
第一行包含两个正整数N和F,1≤N,F≤10000,表示派的数量和朋友的数量。
第二行包含N个1到10000之间的整数,表示每个派的半径。
输出格式
输出每个人能得到的最大的派的体积,精确到小数点后三位。
样例输入
3 3
4 3 3
样例输出
25.133
#include<iostream>
#include<math.h>
using namespace std;
#define PI M_PI
const int N=1e4+5;
int n,f;
double a[N];bool check(double mid){int cnt=0;for(int i=0;i<n;i++){cnt+=a[i]/mid;}if(cnt>=f) return true;else return false;
}int main(){cin>>n>>f;f=f+1;//自己也要分一个派 for(int i=0;i<n;i++){cin>>a[i]; }double left=0,right=-1,mid;for(int i=0;i<n;i++){a[i]=PI*a[i]*a[i];//转化为派的体积if(a[i]>right){//找右边界right,right为最大的派的体积,最终的答案范围为0~right right=a[i];}} while(right-left>=1e-5){mid=(left+right)/2;if(check(mid)){//可以给所有人分 left=mid;}else{right=mid;}} printf("%.3lf ",left);return 0;
}
思路:分治。答案只可能在 0~最大的派的体积 之间。