zoukankan      html  css  js  c++  java
  • poj 3334 Connected Gheeves (Geometry + BInary Search)

    3334 -- Connected Gheeves

      题意是,给出两个尖形的相连的容器,要求向其中灌水。它们具有日常的物理属性,例如两个容器中水平面高度相同以及水高于容器顶部的时候就会溢出。开始的时候打算直接用几何的计算,求出精确值。后来发现,这样的计算实在是太麻烦了,实现起来有很多细节要注意。于是,后来就想到了用二分的方法,枚举水平面的高度,然后求直线切割容器得到的多边形的面积,因为这个面积会随着水平面的高度具有单调性。注意预先确定好二分的上下界即可。1y~

    代码如下:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <cmath>
     6 
     7 using namespace std;
     8 
     9 const double EPS = 1e-10;
    10 const double FINF = 1e10;
    11 const int N = 1111;
    12 inline int sgn(double x) { return (x > EPS) - (x < -EPS);}
    13 struct Point {
    14     double x, y;
    15     Point() {}
    16     Point(double x, double y) : x(x), y(y) {}
    17     bool operator < (Point a) const { return sgn(x - a.x) < 0 || sgn(x - a.x) == 0 && sgn(y - a.y) < 0;}
    18     bool operator == (Point a) const { return sgn(x - a.x) == 0 && sgn(y - a.x) == 0;}
    19 } ;
    20 typedef Point Vec;
    21 Vec operator + (Vec a, Vec b) { return Vec(a.x + b.x, a.y + b.y);}
    22 Vec operator - (Vec a, Vec b) { return Vec(a.x - b.x, a.y - b.y);}
    23 Vec operator * (Vec a, double p) { return Vec(a.x * p, a.y * p);}
    24 Vec operator / (Vec a, double p) { return Vec(a.x / p, a.y / p);}
    25 
    26 template<class T> T sqr(T x) { return x * x;}
    27 inline double dotDet(Vec a, Vec b) { return a.x * b.x + a.y * b.y;}
    28 inline double crossDet(Vec a, Vec b) { return a.x * b.y - a.y * b.x;}
    29 inline double dotDet(Point o, Point a, Point b) { return dotDet(a - o, b - o);}
    30 inline double crossDet(Point o, Point a, Point b) { return crossDet(a - o, b - o);}
    31 
    32 double polyArea(Point *pt, int n) {
    33     double ret = 0.0;
    34     pt[n] = pt[0];
    35     for (int i = 0; i < n; i++) ret += crossDet(Point(0.0, 0.0), pt[i], pt[i + 1]);
    36     return fabs(ret) / 2.0;
    37 }
    38 inline Point lineIntersect(Point P, Vec u, Point Q, Vec v) { return P + u * (crossDet(v, P - Q) / crossDet(u, v));}
    39 
    40 Point gheef[2][N], tmp[N];
    41 double bottom[2];
    42 int n[2];
    43 
    44 double getArea(double x, int id) {
    45     if (x <= bottom[id]) return 0.0;
    46     Point s = Point(-FINF, x), t = Point(FINF, x);
    47     for (int i = 0; i < n[id]; i++) tmp[i] = gheef[id][i];
    48     int l = 0, r = n[id] - 1;
    49     while (crossDet(tmp[l], s, t) * crossDet(tmp[l + 1], s, t) > 0) l++;
    50     while (crossDet(tmp[r], s, t) * crossDet(tmp[r - 1], s, t) > 0) r--;
    51     tmp[l] = lineIntersect(s, t - s, tmp[l], tmp[l + 1] - tmp[l]);
    52     tmp[r] = lineIntersect(s, t - s, tmp[r], tmp[r - 1] - tmp[r]);
    53     return polyArea(tmp + l, r - l + 1);
    54 }
    55 
    56 double getArea(double x) {
    57     double ret = 0.0;
    58     for (int i = 0; i < 2; i++) {
    59         ret += getArea(x, i);
    60     }
    61     return ret;
    62 }
    63 
    64 double dc2(double x) {
    65 //    cout << getArea(3.536) << endl;
    66     double l = min(bottom[0], bottom[1]), r = min(min(gheef[0][0].y, gheef[1][0].y), min(gheef[0][n[0] - 1].y, gheef[1][n[1] - 1].y));
    67 //    cout << l << " l r " << r << endl;
    68     while (l + 1e-5 < r) {
    69         double m = (l + r) / 2.0;
    70         if (getArea(m) > x) r = m;
    71         else l = m;
    72     }
    73     return l;
    74 }
    75 
    76 int main() {
    77 //    freopen("in", "r", stdin);
    78     int T;
    79     double v;
    80     cin >> T;
    81     while (T-- && cin >> v) {
    82         for (int i = 0; i < 2; i++) {
    83             cin >> n[i];
    84             bottom[i] = FINF;
    85             for (int j = 0; j < n[i]; j++) {
    86                 cin >> gheef[i][j].x >> gheef[i][j].y;
    87                 bottom[i] = min(bottom[i], gheef[i][j].y);
    88             }
    89         }
    90         printf("%.3f
    ", dc2(v));
    91     }
    92     return 0;
    93 }
    View Code

    ——written by Lyon

  • 相关阅读:
    ASCII码对照表
    createPopup 超链接
    说说回车键触发表单提交的问题
    linux下配java环境的小结
    spring bind checkbox 传递值问题
    用Common validator为springMVC做验证时遇到的一个问题小记
    [转载]对android LinearLayout中layout_weight属性使用初探
    linux下tomcat启动正常,但用http://22.22.33.33:8080却访问不了,防火墙的设置问题
    Java 遍历Map时 删除元素
    ftp用户登录时不能进自己的目录,被拒绝登录的解决方法
  • 原文地址:https://www.cnblogs.com/LyonLys/p/poj_3334_Lyon.html
Copyright © 2011-2022 走看看