POJ 1434 Fill the Cisterns! (模拟 or 二分)

Fill the Cisterns!

题目连接:

http://acm.hust.edu.cn/vjudge/contest/129783#problem/Fnode

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.
ios

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.
git

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.
spa

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

Source


2016-HUST-线下组队赛-3
code


题意:


给出n个长方体水箱,从下往上依次注入V升水. 求最后结果的高度.
排序


题解:


对长方体的上下底面排序后直接模拟便可,维护当前高度时长方体的截面面积之和. 每次枚举到下底时把面积加入,枚举到下底时减去面积.
当枚举到某个上底时,水不够注满到这个高度,那么用剩余体积除以当前截面,就是剩下的高度.
还有种作法是二分最终高度,并遍历全部长方体计算是否可以用.


这道水题成为了今天的败笔. 2个多小时才过.
一开始就想的是二分,而后我特地处理都乘了个100来避免浮点数. 结果WA. 应该是由于可能不能刚好用完致使的.
而后改为double的仍是WA. 后来重写了一份模拟,仍是WA.
错点在于,一开始把rounded up错误理解成为向上取整,结果每次输出我都加了个0.005致使GG.
模拟过了以后觉得二分的精度不够,这题不能用二分. 回来补题才发现输出必定只能用 %f , 不能用 %lf. (否者WA,至于精度,各类姿式处理都能过).


double输出再用%lf就吃键盘!!!!!
ip


代码:

模拟:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <list>
#define LL long long
#define eps 1e-8
#define maxn 50010
#define mod 100000007
#define inf 0x3f3f3f3f3f3f3f3f
#define mid(a,b) ((a+b)>>1)
#define IN freopen("in.txt","r",stdin);
using namespace std;

int n;
LL V;
struct node {
    LL b,h,w,d;
}p[maxn];

bool vis[maxn];
typedef pair<LL,int> pii;
pii edge[maxn*2];


int main(int argc, char const *argv[])
{
    //IN;

    int t; cin >> t;
    while(t--)
    {
        scanf("%d", &n);
        int cnt = 0;
        for(int i=1; i<=n; i++) {
            scanf("%I64d %I64d %I64d %I64d", &p[i].b, &p[i].h, &p[i].w, &p[i].d);
            edge[++cnt] = make_pair(p[i].b, i);
            edge[++cnt] = make_pair(p[i].b + p[i].h, i);
        }
        scanf("%I64d", &V);

        sort(edge+1, edge+1+2*n);
        memset(vis, 0, sizeof(vis));
        LL area = 0;
        LL ans = edge[1].first;
        double last = inf;
        for(int i=1; i<=2*n; i++) {
            LL top = edge[i].first;
            int num = edge[i].second;

            if((top-ans)*area >= V) {
                last = (double)V / (double)area;
                V = 0;
                break;
            }

            if(vis[num]) {
                V -= area * (top-ans);
                area -= p[num].w*p[num].d;
                ans = top;
            } else {
                V -= area * (top-ans);
                area += p[num].w*p[num].d;
                vis[num] = 1;
                ans = top;
            }
        }

        if(V > 0) printf("OVERFLOW\n");
        else {
            printf("%.2f\n", last+(double)ans);
        }
    }

    return 0;
}

二分:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <list>
#define LL long long
#define eps 1e-8
#define maxn 50010
#define mod 100000007
#define inf 0x3f3f3f3f
#define mid(a,b) ((a+b)>>1)
#define IN freopen("in.txt","r",stdin);
using namespace std;

int n;
double V;
struct node {
    double b,h,w,d;
    bool operator < (const node& B) const {
        return b < B.b;
    }
}p[maxn];

double cal(double dep) {
    double ret = V;
    for(int i=1; i<=n && dep>=p[i].b; i++) {
        if(dep >= p[i].b + p[i].h) ret -= p[i].h * p[i].w * p[i].d;
        else ret -= (dep - p[i].b) * p[i].w * p[i].d;
        if(ret < 0) break;
    }
    return ret;
}


int main(int argc, char const *argv[])
{
    //IN;

    int t; cin >> t;
    while(t--)
    {
        scanf("%d", &n);
        double L = inf, R = -inf;
        for(int i=1; i<=n; i++) {
            scanf("%lf %lf %lf %lf", &p[i].b, &p[i].h, &p[i].w, &p[i].d);
            L = min(L, p[i].b);
            R = max(R, p[i].b + p[i].h);
        }
        scanf("%lf", &V);

        double tmp = V;
        for(int i=1; i<=n; i++) {
            tmp -= p[i].h*p[i].w*p[i].d;
            if(tmp < 0) break;
        }

        if(tmp > 0) {
            printf("OVERFLOW\n");
            continue;
        }

        sort(p+1, p+1+n);

        double mid;
        double ans = inf;
        while(L <= R) {
            mid = (L + R) / 2.0;
            double cur = cal(mid);
            if(cur <= 0) {
                if(fabs(cur) < eps) ans = min(ans, mid);
                R = mid - 0.001;
            }
            else L = mid + 0.001;
        }
        ans = min(ans, mid);

        printf("%.2f\n", ans);
    }

    return 0;
}
相关文章
相关标签/搜索