HDU-1969 Pie 二分法

Problem Description

My birthday is coming up and traditionally I’m serving pie. Not just one pie, no, I have a number N of them, of various tastes and of various sizes. F of my friends are coming to my party and each of them gets a piece of pie. This should be one piece of one pie, not several small pieces since that looks messy. This piece can be one whole pie though.

My friends are very annoying and if one of them gets a bigger piece than the others, they start complaining. Therefore all of them should get equally sized (but not necessarily equally shaped) pieces, even if this leads to some pie getting spoiled (which is better than spoiling the party). Of course, I want a piece of pie for myself too, and that piece should also be of the same size.

What is the largest possible piece size all of us can get? All the pies are cylindrical in shape and they all have the same height 1, but the radii of the pies can be different.

Input One

line with a positive integer: the number of test cases. Then for each test case:
—One line with two integers N and F with 1 <= N, F <= 10 000: the number of pies and the number of friends.
—One line with N integers ri with 1 <= ri <= 10 000: the radii of the pies.

Output

For each test case, output one line with the largest possible volume V such that me and my friends can all get a pie piece of size V. The answer should be given as a floating point number with an absolute error of at most 10^(-3).

Sample Input

3
3 3
4 3 3
1 24
5
10 5
1 4 2 3 4 5 6 5 4 2

Sample Output

25.1327
3.1416
50.2655

先贴个中文翻译…
我的生日快到了,传统上我是在做馅饼。不仅仅是一个馅饼,不,我有很多馅饼,口味各异,大小各异。我的一个朋友要来参加我的聚会,他们每人得到一块馅饼。这应该是一块馅饼,而不是几小块,因为看起来很乱。不过,这一块可以是一整块馅饼。 我的朋友们都很烦人,如果他们中的一个得到了比其他人更大的一块,他们就会开始抱怨。因此,他们所有人都应该得到同样大小(但不一定是同样形状)的馅饼,即使这会导致一些馅饼被宠坏(这比宠坏党要好)。当然,我也想要一块派给自己,而且那块也应该是同样大小的。 我们能得到的最大尺寸是多少?所有的馅饼都是圆柱形的,它们都有相同的高度1,但是馅饼的半径可以不同。

题目大意就是给你两个数字一个代表饼的数量,一个代表人数再给你一组关于饼半径大小的数据(饼的高度都是1),让你给这些人分饼,注意这里是要求每个人分的饼的体积最大,而且每块饼只能分成几小部分,而不能将其拼凑起来

还有一个坑,加上自己一共应该有n+1个人分饼

也就是说,我们对最终分的的饼体积的最大值最小值都能有一定的把握,这是一道简单的二分题目,如果我们一个一个饼进行计算,过程十分麻烦难以考虑,而且容易超时,于是可以考虑二分,先给定一个最大值"max=最大半径的平方",在输入数据时可以顺手将max找出来,定义一个min=0.即从0到饼的最大半径的平方进行二分。因为我们分的是体积,一定注意V=pi*R^2×h因此分的不能是半径。

代码如下(不够简洁AC了就没整理):

#include <iostream>
#include <stdio.h>
#include <cmath>

using namespace std;
const double PI = acos(-1.0);
int main(){
	int n,m;
	double p=1e-7;
	cin>>n;//n是总测试样例 
	for(int i=0;i<n;i++){
		int number[10000]={0},sum=0;
		double bottle=0,top=0,average=0,max=0,o=0;
		cin>>m>>o;//m馅饼的数量,o人的数量 
		o=o+1;//加上自己 
		for(int j=0;j<m;j++){
			cin>>number[j];
			number[j]*=number[j];
			if(number[j]>max){
				max=number[j];
			}
		}
		bottle=0;
		top=max;
		while(top-bottle>p){//double类型的变量不能用top>=bottle跳出,否则会无限循环,必须设置一个精度
		average=(bottle+top)/2;
		for(int j=0;j<m;j++){
			sum+=(int)(number[j]/average);//向下取整,顺便一提ceil()向上取整函数
		}
	     if(sum>=o){//sum表示的是满足当前大小的饼的数量,当sum>=o时说明饼太多可以分得更大
			bottle=average;
		}
		else{
			top=average;
		}
		sum=0;
	}
	printf("%.4lf\n",bottle*PI);//bottle是一定可以的值
	}
	return 0;
} 
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值