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

 

你可能感兴趣的:(poj)