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.
![](http://poj.org/images/2826_1.gif)
Your mission is to calculate how much rain these two boards can collect.
![](http://poj.org/images/2826_1.gif)
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, x1, y1, x2, y2, x3, y3, x4, y4. (x1, y1), (x2, y2) are the endpoints of one board, and (x3, y3), (x4, y4) are the endpoints of the other one.
Each test case consists of 8 integers not exceeding 10,000 by absolute value, x1, y1, x2, y2, x3, y3, x4, y4. (x1, y1), (x2, y2) are the endpoints of one board, and (x3, y3), (x4, y4) 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):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }