poj 3122 Pie

原题 : http://poj.org/problem?id=3122

//poj 3122 
//题意:我有n块圆柱体形状的蛋糕,他们的半径大小不一,现在我来了m个朋友,我要切蛋糕给他们,要求每块蛋糕的大小相同,求出每个人可以分到的蛋糕的最大体积 
//     每个人分到的必须是一块,不能是由两小块拼凑起来的。
//     给出蛋糕的数目,朋友的数目以及每块蛋糕的半径,求出结果 
//思路:二分+贪心。设最大那块蛋糕的体积为r,最小是l(l=0),则结果的范围是已知的,即l~r,用二分查找mid=(l+r)/2;
//     每次得到mid,检查mid是否合法。方式:假设mid是结果,求出最多可以切成多少块mid大小的蛋糕,再和人数m比较。
//     逐渐缩小区间,直到求出结果
//注意①精度问题,不让调用库函数的PI....PI的值要足够精确 ②题目给出的人数是朋友的人数,还应该加上自己,自己也要吃 ③题目给出的是蛋糕的半径不是体积 
#include<iostream> 
#include<cstdio>
#include<algorithm>
using namespace std;
double pie[10001];
int n,m;
const double PI=3.1415926535898;//圆周率要准,3.1415926535898 
int check(double per)
{
	int cnt=0;
	for(int i=0;i<n;i++)
	{
		cnt=cnt+(int)(pie[i]/per);
	}
	if(cnt>=m){ //合法 
		return 1;
	}
	return 0;//不合法 
}
int cmp(double a,double b)
{
	return a<b;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d %d",&n,&m);
		m=m+1; //加上自己 
		for(int i=0;i<n;i++)
		{
			scanf("%lf",&pie[i]);
			pie[i]=PI*pie[i]*pie[i]*10000;//精度处理 
		}
		sort(pie,pie+n,cmp);
		double r=pie[n-1]; 
		double l=0;//得到结果的范围 
		double rs;//存放结果值 
		while(l<=r)//二分 
		{
			double mid=(l+r)/2;
			if(check(mid)){
				rs=mid;
				l=mid+0.01;
			}else{
				r=mid-0.01;
			}
		}
		printf("%.4lf\n",rs/10000);
	}
	return 0; 
}          //AC       






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值