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;
}
查看12道真题和解析