二分答案的经典题。所谓二分答案,即在整个可能的答案空间内进行二分操作,每次都检验一下mid,并根据检验结果调整lef和rig的值。
代码如下:
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cmath>
#define pi acos(-1.0) //用反三角函数计算Pi
using namespace std;
double arr[10005];
int f,n;
bool cmp(double a,double b)
{
return a<b;
}
bool check(double todo)
{
int sum=0;
for(int i=0;i<n;i++)
sum+=(int)(arr[i]/todo); //计算当前体积下能分出多少份派
if(sum>=f) //如果可以分出不少于f(f在main中修改过,f=f+1)块,则当前体积可行
return true;
return false;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n>>f;
f+=1;
for(int i=0;i<n;i++)
{
cin>>arr[i];
arr[i]=arr[i]*arr[i]*pi;
}
sort(arr,arr+n,cmp);
double l=0;double r=arr[n-1];
double mid=l+((r-l)/2);
while(r-l>1e-6) //注意精度
{
mid=l+((r-l)/2);
if(check(mid)) //有些时候不一定是l=mid或r=mid,有可能是l=mid+1或
l=mid; //r=mid-1,这要根据情况而定。但一般而言,如果是浮点数,
else //只需l=mid或r=mid
r=mid;
}
printf("%.4lf\n",mid);
}
return 0;
}