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; 
}   

全部评论

相关推荐

09-23 16:24
河海大学 C++
俺的offer在哪:至少还有感谢信,我连感谢信都没发,三面完隔天状态查询就是未通过😂
点赞 评论 收藏
分享
和蔼:在竞争中脱颖而出,厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务