hdu_1969_NWERC2006_Pie(二分)

来源:互联网 发布:金融炼金术知乎 编辑:程序博客网 时间:2024/06/05 03:17
題意:F+1個人平分N個圓,第i個圓的半徑爲ri,使得每個人得到的面積相等且使得分到的面積儘量的大,每個人得到的部分不必是一個完整的圓形分析:初看這個題目以爲是一個數學題,二分可以說是比較完美的解決這個題目了二分枚舉分到的面積area,判斷則是對每個圓可以切割出多少個這樣的面積,所有圓可以切割的分數如果多於F+1個人,那麼當前面積可以切分,使用二分逼近最終得到結果,需要注意的是,二分的時候浮點數的比較,如果處理不好會一直死循環Code:#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>using namespace std;#define MAXN    10000 + 10double 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_JUDGEfreopen("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;}