您的位置:首页 > 其它

poj 3122 Pie 二分

2012-08-18 13:43 309 查看
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
;

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: