HDU1086 You can Solve a Geometry Problem too

PS: 主要解决线段相交中规范相交和不规范相交。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;

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, point B) {
    return point(A.x-B.x, A.y-B.y);
}
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;
}
int n;

struct line{
    point a, b;
};

bool ok(line t1, line t2) {
    point A = t1.a, B = t1.b;
    point C = t2.a, D = t2.b;
    if(dcmp(Cross(B-A, D-A)*Cross(B-A, C-A))<0 &&
       dcmp(Cross(D-C, A-C)*Cross(D-C, B-C))<0)
       {
            return true;
       }
    if(dcmp(Cross(B-A, C-A))==0) {
        if(dcmp(Dot(A-C, B-C))<=0) return true;
    }
    if(dcmp(Cross(B-A, D-A))==0) {
        if(dcmp(Dot(A-D, B-D))<=0) return true;
    }
    return false;
}

vector<line> v;
int work() {
    int cnt = 0;
    bool res;
    int len = v.size();
    for(int i = 0; i < len; i++) {
        for(int j = i+1; j < len; j++) {
            res = ok(v[i], v[j]);
            if(res) cnt++;
        }
    }
    return cnt;
}

int main()
{
    int n;
    line t;
    while(scanf("%d", &n)!=EOF && n) {
        v.clear();
        for(int i = 0; i < n; i++) {
            scanf("%lf%lf%lf%lf", &t.a.x, &t.a.y, &t.b.x, &t.b.y);
            v.push_back(t);
        }
        int res = work();
        printf("%d\n", res);
    }
    return 0;
}

你可能感兴趣的:(HDU1086 You can Solve a Geometry Problem too)