POJ 3122 Pie(二分枚举)

题目链接:POJ 3122 Pie(二分枚举)
在这里插入图片描述
在这里插入图片描述
题没读懂,求了个平均值QAQ

【题意】

大致题意为就是公平地分披萨pie,有n个pie,找来f个朋友,加上自己那么总人数共 f+1人(注意)。每个pie都是高为1的圆柱体,输入这n个pie的半径,如果要公平地把pie分给每一个人(就是所有人得到的pie尺寸一致,但是形状可以不同),而且每个人得到的那份pie必须是从同一个pie上得到的(注意这个陷阱)。

就是说如果有3个pie, 尺寸分别为1,2,3,如果要给每人尺寸为2的pie,那么最多分给2个人,而不是3个人因为第一个pie尺寸为1,小于2,应该被扔掉。第二个pie尺寸为2,等于2,刚好分给一个人。第三个pie尺寸为3,切出尺寸为2的一份,分给一个人,剩下的尺寸为1的就扔掉千万不要陷入 (1+2+3)/2=3人的误区,这样就变成求平均了(注意)这是一个二分法的题目,我们不断进行二分演算就可以了,还要注意的就是精度的问题

【解题思路】

设每人最多能得到的派为 x,首先可以确定 x 不会超过最大的一块派,所以x的上限就为max(派i),进入二分查找最大的x,二分思路如下:如果可以按照x分,尝试下更大的(low=mid);如果不能,就尝试小一些的(high=mid)。

#include<iostream>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>

using namespace std;
typedef long long ll;
const int MOD = 10000007;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-6;	//根据题目要求设置精度,第一次的1e-8超时了 
const int maxn = 10010;
double v[maxn];	 //体积
int n,f;

bool check(double x)
{
	int cnt = 0;
	for(int i=0;i<n;i++)
	{
		cnt += (int)(v[i]/x);
		if(cnt>=f+1)	//注意f+1个人 
			return true;
	}
	return false;
}

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&f);
		
		double maxsize = 0;		//寻找最大尺寸作为二分上界 
		
		for(int i=0;i<n;i++)
		{
			scanf("%lf",&v[i]);	 //输入半径 
			v[i] = v[i]*v[i]*PI;	//体积
			if(v[i]>maxsize)
				maxsize = v[i];
		}
		
		double l = 0;	//二分下界 
		double r = maxsize;		//二分上界 
		double mid;
		
		while(r-l>eps)	//浮点数比较与整数不同,注意精度的选择 
		{
			mid = (r+l)/2;
			if(check(mid))
				l = mid;
			else
				r = mid;
		}
		
		printf("%.4f\n",mid);
	}
	return 0;
}

在POJ上交代码时,最后的输出只能是%.4f 不能是%.4lf。

猜你喜欢

转载自blog.csdn.net/qq_42815188/article/details/89531713