hdu1558计算几何加并查集

不知道杭电题目分类是咋分的,这题我是在“匹配”里找到的,太假了。这明显是计算几何加并查集嘛。当然,并查集部分很简单,主要就是计算几何了,打了两个小时,我了个去,计算几何功底还是不行啊。。。

/*

 * hdu1558/win.cpp

 * Created on: 2012-8-16

 * Author    : ben

 */

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <cmath>

#include <ctime>

#include <iostream>

#include <algorithm>

#include <queue>

#include <set>

#include <map>

#include <stack>

#include <string>

#include <vector>

#include <deque>

#include <list>

#include <functional>

#include <numeric>

#include <cctype>

using namespace std;

const int MAXN = 1005;



#define zero(x) (((x)>0?(x):-(x))<eps)

const double eps = 1e-8;

typedef double typec;

typedef struct MyPoint {

    typec x;

    typec y;

}MyPoint;

typedef struct MyLine {

    MyPoint a;

    MyPoint b;

}MyLine;

inline double xmult(MyPoint p1, MyPoint p2, MyPoint p0) {

    return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);

}

int dots_inline(MyPoint p1, MyPoint p2, MyPoint p3) {

    return !xmult(p1, p2, p3);

}

inline int same_side(MyPoint p1, MyPoint p2, MyLine l) {

    return xmult(l.a, p1, l.b) * xmult(l.a, p2, l.b) > eps;

}

inline typec xmult(typec x1, typec y1, typec x2, typec y2, typec x0, typec y0) {

    return (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0);

}

inline int dot_online_in(typec x, typec y, typec x1, typec y1, typec x2,

        typec y2) {

    if ((zero(x-x1) && zero(y-y1)) || (zero(x-x2) && zero(y-y2))) {

        return 2;

    }

    if (!zero(xmult(x,y,x1,y1,x2,y2))) {

        return -1;

    }

    if ((x1 - x) * (x2 - x) < eps && (y1 - y) * (y2 - y) < eps) {

        return 0;

    }

    return 1;

}

inline int dot_online_in(const MyPoint &p, const MyLine &l) {

    return dot_online_in(p.x, p.y, l.a.x, l.a.y, l.b.x, l.b.y);

}



//包括端点和部分重合

bool intersect_in(MyLine u, MyLine v) {

    if (!dots_inline(u.a, u.b, v.a) || !dots_inline(u.a, u.b, v.b))

        return !same_side(u.a, u.b, v) && !same_side(v.a, v.b, u);

    return dot_online_in(u.a, v) || dot_online_in(u.b, v)

            || dot_online_in(v.a, u) || dot_online_in(v.b, u);

}

int myset[MAXN], N;

MyLine lines[MAXN];

void initset() {

    for(int i = 0; i < MAXN; i++) {

        myset[i] = i;

    }

}

inline int myfind(int x) {

    return myset[x];

}

void mymerge(int a, int b) {

    if(a > b) {

        a = a ^ b;

        b = a ^ b;

        a = a ^ b;

    }

    for(int k = 0; k <= N; k++) {

        if(myset[k] == b) {

            myset[k] = a;

        }

    }

}

int main() {

#ifndef ONLINE_JUDGE

    freopen("data.in", "r", stdin);

#endif

    int T, K, t;

    char c;

    scanf("%d", &T);

    while(T--) {

        initset();

        scanf("%d", &K);

        N = 0;

        while(K--) {

            scanf(" %c", &c);

            if(c == 'P') {

                scanf("%lf%lf%lf%lf", &lines[N].a.x, &lines[N].a.y, &lines[N].b.x, &lines[N].b.y);

                for(int i = 0; i < N; i++) {

                    if(intersect_in(lines[i], lines[N])) {

                        mymerge(myfind(i), myfind(N));

                    }

                }

                N++;

            }else if(c == 'Q'){

                scanf("%d", &t);

                t = myfind(t - 1);

                int ans = 0;

                for(int i = 0; i < N; i++) {

                    if(myset[i] == t) {

                        ans++;

                    }

                }

                printf("%d\n", ans);

            }

        }

        if(T > 0) {

            putchar('\n');

        }

    }

    return 0;

}

你可能感兴趣的:(HDU)