poj 3122 Pie 二分
poj 3122 Pie 二分
//poj 3122 Pie //二分 //题意: //给出pie和人的数量,要把这些pie平均分给每个人 //思路: //先用pie的半径r平方代替面积,到最后再乘上PI //求出所有r^2的和,除以人数当做二分的high,low=0 //接着相当于对每个人得到的体积进行二分 //每一次二分要计算切出来的蛋糕数是否大于等于人数,若是 //则满足条件,否则不满足要缩小没人得到的体积 //注意: //是限定每个人得到的体积后从每块pie切 //若某块pie最后剩的不足一个人份则剩的扔掉 //即如果一个pie体积为3,每个人分得体积为2 //则这个pie要人掉1体积,而不能和别的pie剩下的掺到一起 //即每一块蛋糕要来自同一块儿大蛋糕,因为这样看起来美观 // //用%lf一只wa,用%f就能ac,不知道为什么···纠结了好久 #define infile freopen("in.txt", "r", stdin); #include <stdio.h> #include <math.h> #include <algorithm> using namespace std; const int INF = 1<<30; const int N = 10050; const double PI = acos(-1.0); const double eps = 1e-8; int n_pie, n_man; double radii2[N]; bool is_ok(double mid) { int cnt = 0; for(int i = n_pie-1; i >= 0; --i) { cnt += int(radii2[i] / mid); if(cnt >= n_man) return true; } return false; } double binarySearch(double high) { double low = 0, ans; while(high - low >= eps) { double mid = low + (high-low)/2; if(is_ok(mid)) { ans = mid; low = mid + 1e-5; } else high = mid - 1e-5; } return ans*PI; } int main() { int n_case; scanf("%d", &n_case); while(n_case--) { scanf("%d%d", &n_pie, &n_man); n_man++; double sum = 0; for(int i = 0; i < n_pie; ++i) { int r; scanf("%d", &r); radii2[i] = double(r*r); sum += radii2[i]; } // sort(radii2, radii2+n_pie); // double high = radii2[n_pie-1]; //用 %.4lf 会错,不知为什么 printf("%.4f\n", binarySearch(sum / n_man)); } return 0; }