題意:
F+1個人平分N個圓,第i個圓的半徑爲ri,使得每個人得到的面積相等且使得分到的面積儘量的大,每個人得到的部分不必是一個完整的圓形
分析:
初看這個題目以爲是一個數學題,二分可以說是比較完美的解決這個題目了
二分枚舉分到的面積area,判斷則是對每個圓可以切割出多少個這樣的面積,所有圓可以切割的分數如果多於F+1個人,那麼當前面積可以切分,使用二分逼近最終得到結果,
需要注意的是,二分的時候浮點數的比較,如果處理不好會一直死循環
Code:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN 10000 + 10
double PI = acos(-1.0);
double r[MAXN];
bool valid(double area, int n, int f)
{
int sum = 0;
for(int i = 1; i <= n; i ++) {
sum += (int)(r[i]/area);
}
if( sum >= f ) {
return true;
}
return false;
}
int main(int argc, char **argv)
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
int cas, f, n;
double max_area;
scanf("%d", &cas);
for( ; cas; cas --) {
scanf("%d %d", &n, &f);
max_area = 0.0;
for(int i = 1; i <= n; i ++) {
scanf("%lf", &r[i]);
r[i] = PI*r[i]*r[i];
max_area = max(max_area, r[i]);
}
double L = 0.0;
double R = max_area;
double M, rst = 0.0;
while( L+1e-5 <= R ) {
///printf("L = %.5lf, R = %.5lf\n", L, R);
M = (L+R)/2.0;
if( valid(M, n, f+1) ) {
rst = max(rst, M);
L = M;
}
else {
R = M;
}
}
printf("%.4lf\n", rst);
}
return 0;
}