POJ_1434

    一开始的思路是把w*d看成一个量,这样长方体就变成了长方形,体积也就可以用面积表示了,然后将b离散化,用线段树计算出每个高度区间内有多大面积,然后沿高度由小到大计算一下如果水淹到当前区间需要多少体积,就可以算出最后的水位。

    但实际上有更直接的算法,直接二分水位的高度然后判断水装入容器后是否恰好到这个高度即可。

#include<stdio.h>
#include<string.h>
#define MAXD 50010
#define zero 1e-8
#define INF 2000000
struct cistern
{
int b, h, s;
}c[MAXD];
int N;
double fabs(double x)
{
return x < 0 ? -x : x;
}
int dcmp(double x)
{
return fabs(x) < zero ? 0 : (x < 0 ? -1 : 1);
}
void init()
{
int i, j, k, w, d;
scanf("%d", &N);
for(i = 0; i < N; i ++)
{
scanf("%d%d%d%d", &c[i].b, &c[i].h, &w, &d);
c[i].s = w * d;
}
}
void solve()
{
int i, j, k;
double max, min, mid, v, ans;
scanf("%lf", &v);
min = 0, max = INF;
for(k = 0; k < 50; k ++)
{
mid = (max + min) / 2;
ans = 0;
for(i = 0; i < N; i ++)
{
if(dcmp(mid - c[i].b - c[i].h) >= 0)
ans += c[i].h * c[i].s;
else if(dcmp(mid - c[i].b) > 0)
ans += (mid - c[i].b) * c[i].s;
}
if(dcmp(ans - v) < 0)
min = mid;
else
max = mid;
}
if(dcmp(mid - INF) == 0)
printf("OVERFLOW\n");
else
printf("%.2lf\n", mid);
}
int main()
{
int t;
scanf("%d", &t);
while(t --)
{
init();
solve();
}
return 0;
}