POJ 2826 An Easy Problem?!(线段交点+简单计算)

Description

It's raining outside. Farmer Johnson's bull Ben wants some rain to water his flowers. Ben nails two wooden boards on the wall of his barn. Shown in the pictures below, the two boards on the wall just look like two segments on the plane, as they have the same width. 

Your mission is to calculate how much rain these two boards can collect. 

Input

The first line contains the number of test cases. 
Each test case consists of 8 integers not exceeding 10,000 by absolute value, x1y1x2y2x3y3x4y4. (x1y1), (x2y2) are the endpoints of one board, and (x3y3), (x4y4) are the endpoints of the other one. 

Output

For each test case output a single line containing a real number with precision up to two decimal places - the amount of rain collected. 
 
题目大意:给两条线段,问这两条线段可以接多少面积的雨水。
思路:没有相交的线段不能接水。因为雨是垂直下落的,有时可能会有一条线段遮住了接水的地方导致无法接水。
PS:输出就不加EPS可能会WA,比如某个计算结果是0.004999999999……
 
代码(32MS):
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <cmath>
  6 using namespace std;
  7 
  8 const double EPS = 1e-8;
  9 const double PI = acos(-1.0);//3.14159265358979323846
 10 
 11 inline int sgn(double x) {
 12     return (x > EPS) - (x < -EPS);
 13 }
 14 
 15 struct Point {
 16     double x, y;
 17     Point() {}
 18     Point(double x, double y): x(x), y(y) {}
 19     void read() {
 20         scanf("%lf%lf", &x, &y);
 21     }
 22     bool operator < (const Point &rhs) const {
 23         if(y != rhs.y) return y < rhs.y;
 24         return x < rhs.x;
 25     }
 26     Point operator + (const Point &rhs) const {
 27         return Point(x + rhs.x, y + rhs.y);
 28     }
 29     Point operator - (const Point &rhs) const {
 30         return Point(x - rhs.x, y - rhs.y);
 31     }
 32     Point operator * (const int &b) const {
 33         return Point(x * b, y * b);
 34     }
 35     Point operator / (const int &b) const {
 36         return Point(x / b, y / b);
 37     }
 38     double length() const {
 39         return sqrt(x * x + y * y);
 40     }
 41     Point unit() const {
 42         return *this / length();
 43     }
 44 };
 45 typedef Point Vector;
 46 
 47 double dist(const Point &a, const Point &b) {
 48     return (a - b).length();
 49 }
 50 
 51 double cross(const Point &a, const Point &b) {
 52     return a.x * b.y - a.y * b.x;
 53 }
 54 //ret >= 0 means turn left
 55 double cross(const Point &sp, const Point &ed, const Point &op) {
 56     return sgn(cross(sp - op, ed - op));
 57 }
 58 
 59 double area(const Point& a, const Point &b, const Point &c) {
 60     return fabs(cross(a - c, b - c)) / 2;
 61 }
 62 
 63 struct Seg {
 64     Point st, ed;
 65     Seg() {}
 66     Seg(Point st, Point ed): st(st), ed(ed) {}
 67     void read() {
 68         st.read(); ed.read();
 69     }
 70 };
 71 typedef Seg Line;
 72 
 73 bool isIntersected(const Point &s1, const Point &e1, const Point &s2, const Point &e2) {
 74     return (max(s1.x, e1.x) >= min(s2.x, e2.x)) &&
 75         (max(s2.x, e2.x) >= min(s1.x, e1.x)) &&
 76         (max(s1.y, e1.y) >= min(s2.y, e2.y)) &&
 77         (max(s2.y, e2.y) >= min(s1.y, e1.y)) &&
 78         (cross(s2, e1, s1) * cross(e1, e2, s1) >= 0) &&
 79         (cross(s1, e2, s2) * cross(e2, e1, s2) >= 0);
 80 }
 81 
 82 bool isIntersected(const Seg &a, const Seg &b) {
 83     return isIntersected(a.st, a.ed, b.st, b.ed);
 84 }
 85 
 86 bool isParallel(const Seg &a, const Seg &b) {
 87     return sgn(cross(a.ed - a.st, b.ed - b.st)) == 0;
 88 }
 89 
 90 //return Ax + By + C =0 's A, B, C
 91 void Coefficient(const Line &L, double &A, double &B, double &C) {
 92     A = L.ed.y - L.st.y;
 93     B = L.st.x - L.ed.x;
 94     C = L.ed.x * L.st.y - L.st.x * L.ed.y;
 95 }
 96 
 97 Point intersection(const Line &a, const Line &b) {
 98     double A1, B1, C1;
 99     double A2, B2, C2;
100     Coefficient(a, A1, B1, C1);
101     Coefficient(b, A2, B2, C2);
102     Point I;
103     I.x = - (B2 * C1 - B1 * C2) / (A1 * B2 - A2 * B1);
104     I.y =   (A2 * C1 - A1 * C2) / (A1 * B2 - A2 * B1);
105     return I;
106 }
107 
108 bool isEqual(const Line &a, const Line &b) {
109     double A1, B1, C1;
110     double A2, B2, C2;
111     Coefficient(a, A1, B1, C1);
112     Coefficient(b, A2, B2, C2);
113     return sgn(A1 * B2 - A2 * B1) == 0 && sgn(A1 * C2 - A2 * C1) == 0 && sgn(B1 * C2 - B2 * C1) == 0;
114 }
115 
116 /*******************************************************************************************/
117 
118 
119 Seg a, b;
120 int n;
121 
122 double solve() {
123     if(!isIntersected(a, b)) return 0;
124     Seg tmp(Point(0, 0), Point(1, 0));
125     if(isParallel(a, tmp) || isParallel(b, tmp) || isParallel(a, b)) return 0;
126     if(a.st.y > a.ed.y) swap(a.st, a.ed);
127     if(b.st.y > b.ed.y) swap(b.st, b.ed);
128     Point O = intersection(a, b);
129     if(b.ed < a.ed) swap(a, b);
130     if(sgn(a.ed.x - O.x) == sgn(b.ed.x - O.x) && (sgn(b.ed.x - O.x) * sgn(cross(b.ed, O, a.ed)) >= 0) &&
131        sgn(fabs(b.ed.x - O.x) - fabs(a.ed.x - O.x)) >= 0) return 0;
132     Point A = a.ed;
133     tmp = Seg(A, Point(A.x + 1, A.y));
134     Point B = intersection(tmp, b);
135     return area(A, B, O);
136 }
137 
138 int main() {
139     scanf("%d", &n);
140     for(int i = 0; i < n; ++i) {
141         a.read(), b.read();
142         printf("%.2f\n", solve() + EPS);
143     }
144 }
View Code

 

posted @ 2013-11-09 17:49  Oyking  阅读(252)  评论(0编辑  收藏  举报