这题用了二分的技巧,二分找一个每块的面积,然后代进去算算最终能得到几份,如果比F+1大或等于,就说明面积太小了,让L=MID,如果比F+1小,就说明面积太大了,让R=MID,注意L=MID的时候包含了等于的情况,所以最终输出L即可。
代码如下
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
double area[10005];
const double PI=acos(-1.0);
int n;
int split(double x){
int sum=0;
int i;
for(i=0;i<n;i++){
sum+=floor(area[i]/x);
}
return sum;
}
int main(){
int i,j;
int T;
scanf("%d",&T);
double max_area=0;
while(T--){
int f;
scanf("%d %d",&n,&f);
for(i=0;i<n;i++){
int r;
scanf("%d",&r);
area[i]=r*r*PI;
max_area=max(max_area,area[i]);
}
double l=0,r=max_area;
while(r-l>1e-5){
double mid=(r+l)/2.0;
if(f+1<=split(mid))
l=mid;
else
r=mid;
}
printf("%.4lf\n",l);
}
return 0;
}