堆坂子的题目。
判断线段相交,共线视为不相交。
求出交点,然后判断在上面的那条线段有没有覆盖住下面的那条线段。
最后输出面积的时候小心输出-0.00的情况。
#include <cstring> #include <cmath> #include <iostream> #include <algorithm> #include <cstdio> using namespace std; typedef unsigned long long ll; #define maxn 111111 #define pi acos (-1) #define rotate Rotate const double eps = 1e-8; int dcmp (double x) { if (fabs (x) < eps) return 0; else return x < 0 ? -1 : 1; } struct point { double x, y; point (double _x = 0, double _y = 0) : x(_x), y(_y) {} point operator - (point a) const { return point (x-a.x, y-a.y); } point operator + (point a) const { return point (x+a.x, y+a.y); } bool operator < (const point &a) const { return x < a.x || (x == a.x && y < a.y); } bool operator == (const point &a) const { return dcmp (x-a.x) == 0 && dcmp (y-a.y) == 0; } }p[maxn]; point operator * (point a, double p) { return point (a.x*p, a.y*p); } double cross (point a, point b) { return a.x*b.y-a.y*b.x; } double dot (point a, point b) { return a.x*b.x + a.y*b.y; } bool OnSegment (point p, point a1, point a2) { return dcmp (cross (a1-p, a2-p) == 0) && dcmp (dot (a1-p, a2-p) <= 0); } bool SegmentProperIntersection (point a1, point a2, point b1, point b2) { double c1 = cross (a2-a1, b1-a1), c2 = cross (a2-a1, b2-a1), c3 = cross (b2-b1, a1-b1), c4 = cross (b2-b1, a2-b1); if (dcmp (c1) == 0 && dcmp (c2) == 0) return 0; //两条线段共线 if (dcmp (c1)*dcmp (c2) < 0 && dcmp (c3)*dcmp (c4) < 0) return 1; else if (OnSegment (a1, b1, b2) || OnSegment (a2, b1, b2) || OnSegment (b1, a1, a2) || OnSegment (b2, a1, a2)) { return 1; } return 0; } point GetLineIntersection (point p, point v, point q, point w) { point u = p-q; double t = cross (w, u) / cross (v, w); return p+v*t; } int n, m, tot; bool ok (point a1, point a2) { if (a1.x*a2.x <= 0) return 1; double ang1 = abs (a1.y/a1.x), ang2 = abs (a2.y/a2.x); if (ang1 > ang2 && fabs (a1.x) >= fabs (a2.x)) return 0; if (ang2 > ang1 && fabs (a2.x) >= fabs (a1.x)) return 0; return 1; } const double INF = 1e30; int main () { //freopen ("in", "r", stdin); int t; scanf ("%d", &t); point a1, a2, b1, b2; while (t--) { cin >> a1.x >> a1.y >> a2.x >> a2.y; cin >> b1.x >> b1.y >> b2.x >> b2.y; if (a1.y > a2.y) swap (a1, a2); if (b1.y > b2.y) swap (b1, b2); if (!SegmentProperIntersection (a1, a2, b1, b2)) { printf ("0.00\n"); } else { point ans = GetLineIntersection (a1, a2-a1, b1, b2-b1); double h = min (a2.y, b2.y); if (dcmp (h-ans.y) == 0 || !ok (a2-ans, b2-ans)) { printf ("0.00\n"); continue; } double p2 = b1.x+(b2.x-b1.x)*(h-b1.y)/(b2.y-b1.y); double p1 = a1.x+(a2.x-a1.x)*(h-a1.y)/(a2.y-a1.y); double area = (p2-p1)*(h-ans.y)/2; printf ("%.2f\n", abs (area)+eps); } } return 0; }