poj1434——二分+精度处理

题目链接:http://poj.org/problem?id=1434

During the next century certain regions on earth will experience severe water shortages. The old town of Uqbar has already started to prepare itself for the worst. Recently they created a network of pipes connecting the cisterns that distribute water in each neighbourhood, making it easier to fill them at once from a single source of water. But in case of water shortage the cisterns above a certain level will be empty since the water will to the cisterns below.


You have been asked to write a program to compute the level to which cisterns will be lled with a certain volume of water, given the dimensions and position of each cistern. To simplify we will neglect the volume of water in the pipes.


Task

Write a program which for each data set:

reads the description of cisterns and the volume of water,

computes the level to which the cisterns will be filled with the given amount of water,

writes the result.

Input

The first line of the input contains the number of data sets k, 1 <= k <= 30. The data sets follow.

The first line of each data set contains one integer n, the number of cisterns, 1 <= n <= 50 000. Each of the following n lines consists of 4 nonnegative integers, separated by single spaces: b, h, w, d - the base level of the cistern, its height, width and depth in meters, respectively. The integers satisfy 0 <= b <= 10^6 and 1 <= h * w * d <= 40 000. The last line of the data set contains an integer V - the volume of water in cubic meters to be injected into the network. Integer V satisfies 1 <= V <= 2 * 10^9.

Output

The output should consist of exactly d lines, one line for each data set.

Line i, 1 <= i <= d, should contain the level that the water will reach, in meters, rounded up to two fractional digits, or the word 'OVERFLOW', if the volume of water exceeds the total capacity of the cisterns.

Sample Input

3
2
0 1 1 1
2 1 1 1
1
4
11 7 5 1
15 6 2 2
5 8 5 1
19 4 8 1
132
4
11 7 5 1
15 6 2 2
5 8 5 1
19 4 8 1
78

Sample Output

1.00
OVERFLOW
17.00

题目翻译:

下个世纪,地球上的某些地区将遭遇严重的缺水。乌克巴尔的老城区已经开始为最坏的情况做准备。最近,他们建立了一个连接蓄水池的管道网络,在每个街区分配水,使得从单一水源一次加水更容易。但是,在缺水的情况下,超过一定水平的蓄水池将是空的,因为水将水将到下面的蓄水池。‎


‎您被要求编写一个程序来计算蓄水池与一定量的水,考虑到每个蓄水池的尺寸和位置的水平。为了简化,我们将忽略管道中的水量。‎




‎任务 为每个数据集编写一个程序:读取‎
‎蓄水池的描述和水的体积,计算蓄水池的级别‎


‎填充了给定的水量,‎

‎写结果。‎

‎输入‎

‎输入的第一行包含数据集 k、 1 <= k <= 30 的数据集数。数据集如下。‎
‎每个数据集的第一行包含一个整数 n,即蓄水池数,1 <= n <= 50 000。 ‎
‎以下每行由 4 个非负整数组成,由单个空格分隔:b、h、w、d - 蓄水池的基本水平、高度、宽度和深度(以米为单位)。整数满足 0 <= b <= 10=6 和 1 <= h = d <= 40 000。数据集的最后一行包含整数 V - 要注入网络的水量(以立方米为单位)。整数 V 满足 1 <= V <= 2 = 10^9。‎

‎输出‎

‎输出应包含正好的 d 行,每个数据集的一行。‎
‎行 i,1 <= i <= d 应包含水将到达的水平(以米为单位,四舍五入为两个小数位数)或单词"OVERFLOW",如果水量超过蓄水池的总‎
‎容量。‎

 

很毒瘤的一道题,思路不难想,二分枚举就行了,但是因为是double类型,所以会有精度误差。

我枚举时的间隔是1e-4,注意判断相等时,不是直接相等,而是前面的比它大,后面的比它小,类比STL中的判断相等的条件。

#include<iostream>
#include<algorithm>
#include<cstdio> 
using namespace std;
const int maxn=5e4+7;
const double eps=1e-4;
const double INF=0x7fffffff;
struct Pipe{
	double b,h,w,d;
	bool operator<(const Pipe &others)const{
		return b<others.b;
	}
}p[maxn];
int n;
double judge(double x){
	double ans=0;
	for(int i=0;i<n;i++){
		if(x<=p[i].b) continue;
		double h=(x-p[i].b)>p[i].h?p[i].h:(x-p[i].b);
		ans+=h*p[i].w*p[i].d;
	}
	return ans; 
} 
int main(){
	int T;
	double V;
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		double res=0;
		double maxn=-INF,minn=INF;
		for(int i=0;i<n;i++){
			scanf("%lf%lf%lf%lf",&p[i].b,&p[i].h,&p[i].w,&p[i].d);
			res+=p[i].h*p[i].w*p[i].d;
			maxn=max(maxn,p[i].b+p[i].h);
			minn=min(minn,p[i].b);
		}
		scanf("%lf",&V);
		sort(p,p+n);
		if(res<V){
			printf("OVERFLOW\n");
			continue;
		}
		else{
			double l=minn,r=maxn,mid;
			while(l<=r){
				mid=(l+r)/2;
				if(judge(mid)>=V&&judge(mid-eps)<V)
					break;
				if(judge(mid)>=V)
					r=mid-eps;
				else 
					l=mid+eps;
			}
			printf("%.2f\n",mid); 
		}	
		
	}
	return 0;
}
/*
3
2
0 1 1 1
2 1 1 1
1
4
11 7 5 1
15 6 2 2
5 8 5 1
19 4 8 1
132
4
11 7 5 1
15 6 2 2
5 8 5 1
19 4 8 1
78
*/ 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值