poj1434Fill the Cisterns!(二分)

链接

题目说给你n个水箱,初始是没有水的,每个的高低位置可能不同,给了你初始的水箱底部所处的水平线位置,问给你V体积水时,水的水平线位置。

直接二分位置p,对于每一个底部低于水平线位置的水箱,里面的水的体积 = min(h,p-b)*w*d;

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 50005
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 struct node
18 {
19     int b,h,w,d;
20 }p[N];
21 int dcmp(double x)
22 {
23     if(fabs(x)<eps) return 0;
24     return x<0?-1:1;
25 }
26 double cal(double mid,int n)
27 {
28     int i;
29     double s = 0;
30     for(i = 1; i <=n;i++)
31     {
32         if(p[i].b>mid) continue;
33         s+=min(mid-p[i].b,p[i].h*1.0)*p[i].w*p[i].d;
34     }
35     return s;
36 }
37 int main()
38 {
39     int v,n,i,t;
40     cin>>t;
41     while(t--)
42     {
43         scanf("%d",&n);
44         double s = 0;
45         for(i =1 ; i <=n; i++)
46         {
47             scanf("%d%d%d%d",&p[i].b,&p[i].h,&p[i].w,&p[i].d);
48             s+=p[i].h*p[i].w*p[i].d;
49         }
50         scanf("%d",&v);
51         if(dcmp(v-s)>0)
52         {
53             puts("OVERFLOW");
54             continue;
55         }
56         double rig = 2000000.0,lef = 0,mid;
57         while(rig-lef>eps)
58         {
59             mid = (rig+lef)/2.0;
60             if(dcmp(cal(mid,n)-v)>=0)
61             rig = mid;
62             else lef = mid;
63         }
64         printf("%.2f\n",rig);
65     }
66     return 0;
67 }
View Code

 

posted @ 2014-08-04 08:46  _雨  阅读(193)  评论(0编辑  收藏  举报