poj2826

要判断线段相交,然后就各种情况分类讨论
虽然过了,但是discuss里某组样例没过
而且还是g++WA, c++A

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const double EPS = 1e-6;

struct Point
{
    Point() {}
    Point(double _x, double _y): x(_x), y(_y) {}

    void input()
    {
        scanf("%lf%lf", &x, &y);
    }

    double getDis(Point &rhs)
    {
        double xx = x - rhs.x;
        xx *= xx;
        double yy = y - rhs.y;
        yy *= yy;
        return sqrt(xx + yy);
    }



    double x, y;
};

Point operator -(Point lhs, Point rhs)
{
    Point ret = Point(lhs.x - rhs.x, lhs.y - rhs.y);
    return ret;
}

double operator ^(Point lhs, Point rhs)
{
    double ret = lhs.x * rhs.y - lhs.y * rhs.x;
    return ret;
}

bool isCross(Point &a, Point &b, Point &c, Point &d)
{
    if(min(a.x, b.x) <= max(c.x, d.x) &&
        min(a.y, b.y) <= max(c.y, d.y) &&
        min(c.x, d.x) <= max(a.x, b.x) &&
        min(c.y, d.y) <= max(a.y, b.y))
    {
        double u, v, w, z;
        u = (c - a) ^ (b - a);
        v = (d - a) ^ (b - a);
        w = (a - c) ^ (d - c);
        z = (b - c) ^ (d - c);
        if(u * v <= EPS && w * z <= EPS && fabs((a - b) ^ (c - d)) > EPS) return true;
    }
    return false;
}

Point getIntersect(Point &a, Point &b, Point &c, Point &d)
{
    double D = (a - b) ^ (c - d);
    double a1 = b.y - a.y, a2 = d.y - c.y;
    double b1 = a.x - b.x, b2 = c.x - d.x;
    double c1 = a ^ (b - a), c2 = c ^ (d - c);
    Point ret = Point((b2 * c1 - b1 * c2) / D, (a1 * c2 - a2 * c1) / D);
    return ret;
}

Point a, b, c, d;
int n;

Point getMaxY(Point &a, Point &b, Point &o)
{
    Point ret = a;
    if(b.y > o.y) ret = b;
    return ret;
}

double solve()
{
    if(isCross(a, b, c, d) && a.y != b.y && c.y != d.y)
    {

        Point o = getIntersect(a, b, c, d);
        Point p = getMaxY(a, b, o);
        Point q = getMaxY(c, d, o);
        Point r, s;
        Point oo = o;
        ++oo.y;
        double s1 = (oo - o) ^ (p - o), s2 = (oo - o) ^ (q - o);
        if(fabs(p.y - q.y) <= EPS)
        {
            r = p;
            s = q;
            goto getSum;
        }
        if(fabs(p.x - q.x) <= EPS) return 0.0;

        if(fabs(p.x - o.x) <= EPS || fabs(q.x - o.x) <= EPS) goto getRS;

        if(s1 * s2 > 0)
        {
            double s3;
            Point temp1 = p - o, temp2 = q - o, temp3 = p - q;
            double k1 = fabs(temp1.y / temp1.x), k2 = fabs(temp2.y / temp2.x);
            double k3 = fabs(temp3.y / temp3.x);
            if(p.y > q.y)
            {
                s3 = (oo - o) ^ (p - q);
            }
            else
            {
                s3 = (oo - o) ^ (q - p);
            }
            if(s3 * s1 > 0 && k3 > k1 && k3 > k2) return 0.0;
            // printf("k3:%lf k2:%lf k1:%lf\n", k3, k2, k1);
        }
    getRS:
        if(p.y > q.y)
        {
            s = q;
            double part1 = s.y - o.y, part2 = p.y - s.y;
            r.x = o.x + (p.x - o.x) * part1 / (part1 + part2);
            r.y = o.y + (p.y - o.y) * part1 / (part1 + part2);
        }
        else
        {
            r = p;
            double part1 = r.y - o.y, part2 = q.y - r.y;
            s.x = o.x + (q.x - o.x) * part1 / (part1 + part2);
            s.y = o.y + (q.y - o.y) * part1 / (part1 + part2);
        }

    getSum:
        // printf("r: %lf %lf\ns: %lf %lf\no:%lf %lf\n", r.x, r.y, s.x, s.y, o.x, o.y);
        double ret = (r - o) ^ (s - o);
        ret = fabs(ret) / 2.0;
        return ret;
    }
    else return 0.0;
}

int main()
{
    // freopen("in.txt", "r", stdin);
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
    {
        a.input();
        b.input();
        c.input();
        d.input();
        printf("%.2f\n", solve());
    }
}