• hdu 1558 Segment set 线段相交+并查集


    Segment set

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)



    Problem Description
    A segment and all segments which are connected with it compose a segment set. The size of a segment set is the number of segments in it. The problem is to find the size of some segment set.

     
    Input
    In the first line there is an integer t - the number of test case. For each test case in first line there is an integer n (n<=1000) - the number of commands. 

    There are two different commands described in different format shown below:

    P x1 y1 x2 y2 - paint a segment whose coordinates of the two endpoints are (x1,y1),(x2,y2).
    Q k - query the size of the segment set which contains the k-th segment.

    k is between 1 and the number of segments in the moment. There is no segment in the plane at first, so the first command is always a P-command.
     
    Output
    For each Q-command, output the answer. There is a blank line between test cases.
     
    Sample Input
    1 10 P 1.00 1.00 4.00 2.00 P 1.00 -2.00 8.00 4.00 Q 1 P 2.00 3.00 3.00 1.00 Q 1 Q 3 P 1.00 4.00 8.00 2.00 Q 2 P 3.00 3.00 6.00 -2.00 Q 5
     
    Sample Output
    1 2 2 2 5
     
    Author
    LL
     
    Source
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<bitset>
    #include<set>
    #include<map>
    #include<time.h>
    using namespace std;
    #define LL long long
    #define bug(x)  cout<<"bug"<<x<<endl;
    const int N=1e3+10,M=2e6+10,inf=1e9+10;
    const LL INF=1e18+10,mod=998244353,MOD=998244353;
    const double eps=1e-8,pi=(4*atan(1.0));
    
    int sgn(double x)
    {
        if(fabs(x) < eps)return 0;
        if(x < 0)return -1;
        else return 1;
    }
    struct Point
    {
        double x,y;
        Point() {}
        Point(double _x,double _y)
        {
            x = _x;
            y = _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;
        }
    //绕原点旋转角度B(弧度值),后x,y的变化
        void transXY(double B)
        {
            double tx = x,ty = y;
            x= tx*cos(B) - ty*sin(B);
            y= tx*sin(B) + ty*cos(B);
        }
    };
    struct Line
    {
        Point s,e;
        Line() {}
        Line(Point _s,Point _e)
        {
            s = _s;
            e = _e;
        }
    //两直线相交求交点 //第一个值为0表示直线重合,为1表示平行,为0表示相交,为2是相交 //只有第一个值为2时,交点才有意义
        pair<int,Point> operator &(const Line &b)const
        {
            Point res = s;
            if(sgn((s-e)^(b.s-b.e)) == 0)
            {
                if(sgn((s-b.e)^(b.s-b.e)) == 0) return make_pair(0,res);//重合
                else return make_pair(1,res);//平行
            }
            double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
            res.x += (e.x-s.x)*t;
            res.y += (e.y-s.y)*t;
            return make_pair(2,res);
        }
    };
    bool inter(Line l1,Line l2)
    {
        return
            max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&
            max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&
            max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&
            max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&
            sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0 &&
            sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) <= 0;
    }
    char ch[N];
    int fa[N],si[N];
    int Find(int x)
    {
        return x==fa[x]?x:fa[x]=Find(fa[x]);
    }
    void update(int u,int v)
    {
        int x=Find(u);
        int z=Find(v);
        if(x!=z)
        {
            fa[x]=z;
            si[z]+=si[x];
        }
    }
    Line a[N];
    int main()
    {
        int T,cas=0;
        scanf("%d",&T);
        while(T--)
        {
            if(cas)printf("
    ");
            cas++;
            int cnt=0;
            for(int i=1;i<=1000;i++)
                fa[i]=i,si[i]=1;
            int q;
            scanf("%d",&q);
            while(q--)
            {
                scanf("%s",ch);
                if(ch[0]=='Q')
                {
                    int x;
                    scanf("%d",&x);
                    int f=Find(x);
                    printf("%d
    ",si[f]);
                }
                else
                {
                    double x1,y1,x2,y2;
                    scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                    Point s(x1,y1),e(x2,y2);
                    a[++cnt]=Line(s,e);
                    for(int i=1;i<cnt;i++)
                        if(inter(a[i],a[cnt]))update(i,cnt);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    关于一个标准的poi下载文件模板 可拿来来直接使用
    关于史上最简单的导出(导出excal)
    关于spring MVC的面试题
    关于响应式布局(pc端访问自适应 手机端访问自适应)
    密码生成器
    关于poi的导出(POI)
    关于MUI一个很实用的前端框架
    (转载)插画版Kubernetes指南(小孩子也能看懂的kubernetes教程)
    (转载)Python tips: 什么是*args和**kwargs?
    python编程中的if __name__ == 'main': 的作用和原理
  • 原文地址:https://www.cnblogs.com/jhz033/p/7515343.html
Copyright © 2020-2023  润新知