zoj 3913 Bob wants to pour water(zoj 2015年10月月賽k題)

Bob wants to pour water

Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge

There is a huge cubiod house with infinite height. And there are some spheres and some cuboids in the house. They do not intersect with others and the house. The space inside the house and outside the cuboids and the spheres can contain water.

Bob wants to know when he pours some water into this house, what's the height of the water level based on the house's undersurface.

Input

The first line is a integer T (1 ≤ T ≤ 50), the number of cases.

For each case:

The first line contains 3 floats wl (0 < wl < 100000), the width and length of the house, v (0 < v < 1013), the volume of the poured water, and 2 integers, m (1 ≤ m ≤ 100000), the number of the cuboids, n (1 ≤ n ≤ 100000), the number of the spheres.

The next m lines describe the position and the size of the cuboids.

Each line contains z (0 < z < 100000), the height of the center of each cuboid, a (0 < a < w), b (0 < b < l), c, the width, length, height of each cuboid.

The next n lines describe the position and the size of the spheres, all these numbers are double.

Each line contains z (0 < z < 100000), the height of the center of each sphere, r (0 < 2r < w and 2r < l), the radius of each sphere.

Output

For each case, output the height of the water level in a single line. An answer with absolute error less than 1e-4 or relative error less than 1e-6 will be accepted. There're T lines in total.

Sample Input

1
1 1 1 1 1
1.5 0.2 0.3 0.4
0.5 0.5

Sample Output

1.537869


題目大意:
   
    給出一個大的立方體容器,給出長和寬,高不限,容器內放小的球體和立方體,給出他們的中心在的位置,現在往容器內放V體積水,求

大容器的水平面的高度。


解題思路:
   
    由於n只有10^5次方,可以直接二分,二分水面的高度就可,球被淹沒的體積可以用截面法很容易算出來。


代碼:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>

using namespace std;

double pi=3.1415926535898;
double w,l,v;
int n,m;
double ch[100010],cw[100010],cl[100010],cg[100010];
double sh[100010],sr[100010];
double av;

double getv(double h)
{
    int i;
    double ans=h*w*l;
    for(i=0;i<n;i++)
    {
        if(h>ch[i]+cg[i]/2)
        {
            ans-=cw[i]*cl[i]*cg[i];
        }
        else if(h<ch[i]-cg[i]/2)
        {
            continue;
        }
        else
        {
            ans-=cw[i]*cl[i]*(h-(ch[i]-cg[i]/2));
        }
    }
    for(i=0;i<m;i++)
    {
        if(h<=sh[i]-sr[i])
            continue;
        if(h>sh[i]+sr[i])
        {
            ans-=(4.0/3)*pi*sr[i]*sr[i]*sr[i];
        }
        else if(h>sh[i])
        {
            double hh=h-sh[i];
            ans-=hh*sr[i]*sr[i]*pi-(1.0/3)*hh*hh*hh*pi+(2.0/3)*pi*sr[i]*sr[i]*sr[i];
        }
        else if(h>sh[i]-sr[i])
        {
            double hh=sh[i]-h;
            ans-=(4.0/3)*pi*sr[i]*sr[i]*sr[i] -( hh*sr[i]*sr[i]*pi-(1.0/3)*hh*hh*hh*pi+(2.0/3)*pi*sr[i]*sr[i]*sr[i]);
        }
    }
    return ans;
}
double geth()
{
    double left=v/(w*l);
    double r=(v+av)/(w*l);

  // printf("%lf\n",l);

   // printf("%.6lf\n",av);
  //   printf("%lf %.6lf\n",left,r);
    // cout<<r-left<<endl;
   // cout<<"ok\n";
  //  cout<<l<<" "<<r<<endl;
  //int cnt=0;
  int cnt=0;
    while(cnt++<100 )
    {
        double mid=(left+r)/2;
        double now=getv(mid);
     //   cout<<mid<<endl;
     //  printf("%.6lf %.6lf\n",now,mid);
        if(now>v)
        {
            r=mid;
        }
        else
        {
            left=mid;
        }
    }
    return left;
}

int main()
{
   //freopen("D:\\in.txt","r",stdin);
    int T,i,j;
    cin>>T;
    while(T--)
    {
        av=0;
        scanf("%lf %lf %lf %d %d",&w,&l,&v,&n,&m);
        for(i=0;i<n;i++)
        {
            scanf("%lf %lf %lf %lf",&ch[i],&cw[i],&cl[i],&cg[i]);
            av+=cw[i]*cl[i]*cg[i];
        }
        for(i=0;i<m;i++)
        {
            scanf("%lf %lf",&sh[i],&sr[i]);
            av+=(4.0/3)*pi*sr[i]*sr[i]*sr[i];
        }
        printf("%.6lf\n",geth());
    }
}


    


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章