E 题貌似有点问题
找了通过的代码对拍了一下,几乎所有如下图所示的两条斜率一正一负的线段相交的情况,输出都是 0.00,但应该标红的这一部分三角形对答案是有贡献的。
如图的这组数据是
1
0 1 -4 -1
-3 4 1 -10
想不出来哪错了,其他的情况对拍好像没有问题。
#pragma GCC optimize("unroll-loops, Ofast") #include<bits/stdc++.h> using namespace std; using i64 = long long; #define endl '\n' mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); i64 n, m, k; void init() {} constexpr double eps = 1e-9; int sgn(double x) { return x < -eps ? -1 : x > eps; } typedef struct Point { double x, y; Point(double x = 0, double y = 0) : x(x), y(y) {} Point operator- (const Point &B) const { return Point(x - B.x, y - B.y); } Point operator+ (const Point &B) const { return Point(x + B.x, y + B.y); } double operator^ (const Point &B) const { return x * B.y - y * B.x; } double operator* (const Point &B) const { return x * B.x + y * B.y; } Point operator* (const double &B) const { return Point(x * B, y * B); } bool operator== (const Point &B) const { return sgn(x - B.x) == 0 && sgn(y - B.y) == 0; } bool operator!= (const Point &B) const { return sgn(x - B.x) || sgn(y - B.y); } } Vector; double operator* (Vector &A, Vector &B) { return A.x * B.x + A.y * B.y; } double operator^ (Vector &A, Vector &B) { return A.x * B.y - A.y * B.x; } int Cross(Point a, Point b, Point c) { return sgn((b - a) ^ (c - a)); } bool In_one_line(Point A, Point B, Point C) { return !sgn((B - A) ^ (C - B)); } bool OnSegment(Point P, Point A, Point B) { Vector PA = A - P, PB = B - P; return sgn(PA ^ PB) == 0 && sgn(PA * PB) <= 0; } bool Intersect_seg(Point a, Point b, Point c, Point d) { if (OnSegment(a, c, d) || OnSegment(b, c, d) || OnSegment(c, a, b) || OnSegment(d, a, b)) return 1; if (Cross(a, b, c) * Cross(a, b, d) >= 0) return 0; if (Cross(c, d, a) * Cross(c, d, b) >= 0) return 0; return 1; } Point Intersection_line(Point a, Point b, Point c, Point d) { Vector u = b - a, v = d - c; double t = ((a - c) ^ v) / (v ^ u); return a + u * t; } void solve() { Point p[4]; cin >> p[0].x >> p[0].y; cin >> p[1].x >> p[1].y; cin >> p[2].x >> p[2].y; cin >> p[3].x >> p[3].y; cout << fixed << setprecision(2); if (!Intersect_seg(p[0], p[1], p[2], p[3])) { cout << 0.00 << endl; return; } if (fabs(p[0].y - p[1].y) < eps || fabs(p[2].y - p[3].y) < eps) { cout << 0.00 << endl; return; } if (p[0].x > p[1].x) { swap(p[0].x, p[1].x); swap(p[0].y, p[1].y); } if (p[2].x > p[3].x) { swap(p[2].x, p[3].x); swap(p[2].y, p[3].y); } if (p[0].x > p[2].x) { swap(p[0].x, p[2].x); swap(p[0].y, p[2].y); swap(p[1].x, p[3].x); swap(p[1].y, p[3].y); } Point c = Intersection_line(p[0], p[1], p[2], p[3]); p[0].x -= c.x, p[0].y -= c.y; p[1].x -= c.x, p[1].y -= c.y; p[2].x -= c.x, p[2].y -= c.y; p[3].x -= c.x, p[3].y -= c.y; c.x = 0, c.y = 0; if (fabs((p[1].y - p[0].y) * (p[3].x - p[2].x) - (p[3].y - p[2].y) * (p[1].x - p[0].x)) < eps) { cout << 0.00 << endl; return; } if ((p[0].y < eps && p[1].y < eps) || (p[2].y < eps && p[3].y < eps)) { cout << 0.00 << endl; return; } double ans = 0; if (p[0].y < p[1].y) { swap(p[0].x, p[1].x); swap(p[0].y, p[1].y); } if (p[2].y < p[3].y) { swap(p[2].x, p[3].x); swap(p[2].y, p[3].y); } double L = (p[1].x - p[0].x) / (p[1].y - p[0].y); double R = (p[3].x - p[2].x) / (p[3].y - p[2].y); if (p[0].y < p[2].y) { double X = R * p[0].y + p[2].x - R * p[2].y; ans += fabs(X - p[0].x) * p[0].y / 2; } else { double X = L * p[2].y + p[0].x - L * p[0].y; ans += fabs(X - p[2].x) * p[2].y / 2; } cout << ans << endl; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); init(); int t = 1; cin >> t; while (t--) { solve(); } return 0; }