zoukankan      html  css  js  c++  java
  • poj3334(Connected Gheeves)

    Connected Gheeves
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 1008   Accepted: 368

    Description

    Gheeves (plural of gheef) are some objects similar to funnels. We define a gheef as a two dimensional object specified by a sequence of points (p1p2, ..., pn) with the following conditions:

    • 3 ≤ n ≤ 1000
    • If a point pi is specified by the coordinates (xiyi), there is an index 1 < c < n such that y1 > y2 > ... > yc and yc < yc+1 < yc+2 < ... < ynpc is called the cusp of the gheef.
    • For all 1 ≤ i < cxi < xc and for all c < i ≤ nxi > xc.
    • For 1 < i < c, the amount of rotation required to rotate pi-1 around pi in clockwise direction to become co-linear with pi and pi+1, is greater than 180 degrees. Likewise, for c < i < n, the amount of rotation required to rotate pi-1 around pi in clockwise rotation to become co-linear with pi and pi+1, is greater than 180 degrees.
    • The set of segments joining two consecutive points of the sequence intersect only in their endpoints.

    For example, the following figure shows a gheef of six points with c = 4:

    We call the sequence of segments (p1p2p2p3, ..., pn-1pn), the body of the gheef. In this problem, we are given two gheeves P = (p1p2, ..., pn) and Q = (q1q2, ..., qm), such that all x coordinates of pi are negative integers and all x coordinates of qi are positive integers. Assuming the cusps of the two gheeves are connected with a narrow pipe, we pour a certain amount of water inside the gheeves. As we pour water, the gheeves are filled upwards according to known physical laws (the level of water in two gheeves remains the same). Note that in the gheef P, if the level of water reaches min(y1yn), the water pours out of the gheef (the same is true for the gheef Q). Your program must determine the level of water in the two gheeves after pouring a certain amount of water. Since we have defined our problem in two dimensions, the amount of water is measured in terms of area it fills. Note that the volume of pipe connecting cusps is considered as zero.

    Input

    The first number in the input line, t is the number of test cases. Each test case is specified on three lines of input. The first line contains a single integer a (1 ≤ a ≤ 100000) which specifies the amount of water poured into two gheeves. The next two lines specify the two gheeves P and Q respectively, each of the form k x1 y1 x2 y2 ... xk yk where k is the number of points in the gheef (n for P and m for Q), and the xiyi sequence specify the coordinates of the points in the sequences.

    Output

    The output contains t lines, each corresponding to an input test case in that order. The output line contains a single integer L indicating the final level of water, expressed in terms of y coordinates rounded to three digits after decimal points.
     

    Sample Input

    2
    25
    3 -30 10 -20 0 -10 10
    3 10 10 20 0 30 10
    25
    3 -30 -10 -20 -20 -10 -10
    3 10 10 20 0 30 10
    

    Sample Output

    3.536
    -15.000
    

    Source

     
     
     

    题意:给定两个凹形的水槽,一个在y轴左半边,一个在右半边。水槽有个最低点,其中最低点左半边y坐标严格递减,右半边严格递增。两个水槽最低点有水管相连。给你a升水,全部灌入水槽后,水面高度为多少?

    题解:二分最终高度,判断面积与a大小关系即可。怎么算高度为h时的面积呢?对于每个水槽,找出y=h与水槽边界两个交点,然后与y=h下方的顶点组成一个多边形,叉积算面积即可。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int inf = 0x3f3f3f3f;
      5 const double eps = 1e-8;
      6 const double pi = acos(-1.0);
      7 const int maxn = 1010;
      8 
      9 int cmp(double x) {
     10     if (fabs(x) < eps) return 0;
     11     if (x > 0) return 1;
     12     return -1;
     13 }
     14 
     15 inline double sqr(double x) {
     16     return x*x;
     17 }
     18 
     19 struct point {
     20     double x, y;
     21     point() {}
     22     point(double a, double b) : x(a), y(b) {}
     23     void input() {
     24         scanf("%lf%lf", &x, &y);
     25     }
     26     friend point operator + (const point& a, const point& b) {
     27         return point(a.x+b.x, a.y+b.y);
     28     }
     29     friend point operator - (const point& a, const point& b) {
     30         return point(a.x-b.x, a.y-b.y);
     31     }
     32     friend bool operator == (const point& a, const point& b) {
     33         return cmp(a.x-b.x)==0 && cmp(a.y-b.y)==0;
     34     }
     35     friend point operator * (const point& a, const double& b) {
     36         return point(a.x*b, a.y*b);
     37     }
     38     friend point operator * (const double& a, const point& b) {
     39         return point(a*b.x, a*b.y);
     40     }
     41     friend point operator / (const point& a, const double& b) {
     42         return point(a.x/b, a.y/b);
     43     }
     44     double norm() {
     45         return sqrt(sqr(x)+sqr(y));
     46     }
     47 };
     48 
     49 double det(const point& a, const point& b) {
     50     return a.x*b.y-a.y*b.x;
     51 }
     52 
     53 double calv(double h, vector<point>& p, int np, int lp) {
     54     int i = 0, j = np-1;
     55     double v = 0;
     56     while (i <= lp && p[i].y > h) ++i;
     57     while (j >= lp && p[j].y > h) --j;
     58     if (i <= j) {
     59         point c = point{p[i].x-(p[i].x-p[i-1].x)*(h-p[i].y)/(p[i-1].y-p[i].y), h};
     60         point d = point{p[j].x+(p[j+1].x-p[j].x)*(h-p[j].y)/(p[j+1].y-p[j].y), h};
     61         for (int k = i; k < j; ++k)
     62             v += det(p[k], p[k+1]);
     63         v += det(p[j], d) + det(d, c) + det(c, p[i]);
     64     }
     65     return fabs(v/2);
     66 }
     67 
     68 int main() {
     69     int T;
     70     cin >> T;
     71     while (T--) {
     72         int np, nq, lp, lq;
     73         vector<point> p(maxn), q(maxn);
     74         double a;
     75         scanf("%lf", &a);
     76         lp = lq = 0;
     77         scanf("%d", &np);
     78         for (int i = 0; i < np; ++i) {
     79             p[i].input();
     80             if (p[i].y < p[lp].y)
     81                 lp = i;
     82         }
     83         scanf("%d", &nq);
     84         for (int i = 0; i < nq; ++i) {
     85             q[i].input();
     86             if (q[i].y < q[lq].y)
     87                 lq = i;
     88         }
     89         double l = min(p[lp].y, q[lq].y), r = (double)inf;
     90         r = min(p[0].y, min(p[np-1].y, min(q[0].y, q[nq-1].y)));
     91         while (fabs(r-l) > eps) {
     92             double m = (l + r) / 2;
     93             double v = calv(m, p, np, lp) + calv(m, q, nq, lq);
     94             if (cmp(v-a) >= 0) {
     95                 r = m;
     96             } else {
     97                 l = m;
     98             }
     99         }
    100         printf("%.3f
    ", r);
    101     }
    102     return 0;
    103 }
  • 相关阅读:
    HttpModule和HttpHandler
    SharePoint
    两种遍历Hashtable方法(小技巧)
    在线游戏开发人员的行话
    AS3 条件编译
    Flash开发MMORPG的时候一些技术障碍
    Java实现几种常见排序方法
    画贝塞尔曲线
    一一解答
    如何留住核心人才?
  • 原文地址:https://www.cnblogs.com/godweiyang/p/5090434.html
Copyright © 2011-2022 走看看