Fill the Cisterns!
Time Limit: 5000MS | Memory Limit: 10000K | |
Total Submissions: 3604 | Accepted: 1214 |
Description
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.
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.
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.
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
一些不同高度 不同大小的水箱组成连通器,装下体积v的液体时,求液面高度
二分0 ~ MAX 之间的高度值,看此时的高度mid能否装下所有的v,找到最小的符合要求的解
最小的原因是 对于第一个样例 高度 [1,2)之间的高度都可以装下所有的v ,但(1,2)之间没有水箱,所以此时的液面高度为1
#include <iostream> #include <cstdio> #include <cstring> #include <stdlib.h> #include <algorithm> #include <queue> #include <map> #include <cmath> #define MAX 2000000 #define eps 1e-10 #define N 50011 using namespace std; struct node { int b, h, s; }q[N]; int n; int dcmp(double x) { return fabs(x) < eps ? 0 : (x < 0? -1 : 1) ; } void solve(double v) { double mid; double low = 0, high = MAX; double ans; for(int j = 0; j < 100; j++) { ans = 0; // 液面高度为mid时,需要的液体体积 mid = (low + high) / 2; //二分枚举可能的液面高度 for(int i = 0; i < n; i++) { if(dcmp(mid - q[i].b - q[i].h) >=0) // 液面完全高于或等于 水箱 { ans += q[i].s * q[i].h; // 加上 水箱的全部体积 } else if(dcmp(mid - q[i].b) > 0) //mid从水箱的中间穿过 { ans += q[i].s * (mid - q[i].b); // 加上 水箱mid以下的体积 } } if(dcmp(ans - v) >= 0) //必须为= mid要最小 high = mid; else low = mid; } printf("%.2f\n",mid); } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d", &n); int w,d; double sum = 0; for(int i = 0; i < n; i++) { scanf("%d%d%d%d", &q[i].b, &q[i].h, &w, &d); //水箱离地高度 和它的高 长 宽 q[i].s = w * d; //水箱底面积 sum += q[i].s * q[i].h; // sum记录所有水箱装满需要的体积 } double v; scanf("%lf", &v); if(dcmp(sum - v) < 0) // <v会溢出 相等不会溢出 { printf("OVERFLOW\n"); continue; } solve(v); } return 0; }