ZOJ 3913 积分

来源:互联网 发布:如何查询别人淘宝id 编辑:程序博客网 时间:2024/06/11 08:26

ZOJ 3913
题目链接:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5640
题意:
往一个立方体容器里面注水。长宽已知,高不可观。
矩阵容器里面有一些不想交的球体和立方体,大小什么的都给出来。
现要注水v升,求水平面相对于立方体容器高度。
思路:
难点在推球体积分公式啊。
其实高数学好就不会有问题,假设水平面和球体是相交的,积分符号为S,那么算出水平面和球体的距离d,则temp = S(PI*(r*r-d*d)),判断一下水平面在球体中心上还是下加个常数就可以。
当然二分的上下界写错会使劲WA这种事我是不会写的。
源码:

#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <iostream>using namespace std;const int MAXN = 100000 + 5;const double PI = 3.1415926535897932384626433832795;const double eps = 1e-6;struct D{    double h, a, b, c;}d[MAXN];struct C{    double h, r;}l[MAXN];int main(){//    freopen("K.in", "r", stdin);//    freopen("ZOJ 3913 WA.out", "w", stdout);    int t;    scanf("%d", &t);    while(t--){        double w, s, v;        int n, m;//        double sum = 0;        double sv = 0;        scanf("%lf%lf%lf%d%d", &w, &s, &v, &n, &m);        for(int i = 0 ; i < n ; i++){            scanf("%lf%lf%lf%lf", &d[i].h, &d[i].a, &d[i].b, &d[i].c);            sv += d[i].a * d[i].b * d[i].c;        }        for(int i = 0 ; i < m ; i++){            scanf("%lf%lf", &l[i].h, &l[i].r);            sv += PI * l[i].r * l[i].r * l[i].r * 4.0 / 3.0;        }//        sv = sum;            double le = v / (w * s), re = (v + sv) / (w * s);            while(fabs(re - le) > eps){                double mid = (re + le) / 2.0;//                printf("re = %f, le = %f, mid = %f\n", re, le, mid);                double sum = 0;                for(int i = 0 ; i < n ; i++){                    if((mid <= d[i].h + d[i].c / 2.0) && (mid >= d[i].h - d[i].c / 2.0)){                        sum += (mid - d[i].h + d[i].c / 2.0) * d[i].a * d[i].b;//                        printf("factor = %f\n", (mid - d[i].h + d[i].c / 2) * d[i].a * d[i].b);                    }                    else if(mid > d[i].h + d[i].c / 2.0)                        sum += d[i].a * d[i].b * d[i].c;                }                for(int i = 0 ; i < m ; i++){                    if((mid <= l[i].h + l[i].r) && (mid >= l[i].h - l[i].r)){                        double u = l[i].h - mid;                        if(u < 0)   u = -u;                        double temp = PI*(l[i].r*l[i].r*u-u*u*u/3.0);                        if(mid > l[i].h)  temp = temp + 2.0 * PI * l[i].r * l[i].r * l[i].r / 3.0;                        else    temp = 2.0 * PI * l[i].r * l[i].r * l[i].r / 3.0 - temp;//                        printf("temp = %f\n", temp);                        sum += temp;//                        double u = mid - (l[i].h - l[i].r);//                        sum += PI * (l[i].r * u * u - u * u * u / 3.0);                    }                    else if(mid > l[i].h + l[i].r){                        sum += l[i].r * l[i].r * l[i].r * PI * 4.0 / 3.0;                    }                }                sum = w * s * mid - sum;//                printf("sum = %.10f\n", sum);                if(sum >= v - eps){                    re = mid;                }                else                    le = mid;            }            printf("%.6f\n", re);    }    return 0;}
0 0
原创粉丝点击