zoukankan      html  css  js  c++  java
  • 线段判交模板

    整理一下模板、才发现原来的写法是错的、郁闷。

    HDU 1086

    You can Solve a Geometry Problem too

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

    Total Submission(s): 7893    Accepted Submission(s): 3853 

    Problem Description
    Many geometry(几何)problems were designed in the ACM/ICPC. And now, I also prepare a geometry problem for this final exam. According to the experience of many ACMers, geometry problems are always much trouble, but this problem is very easy, after all we are now attending an exam, not a contest :) Give you N (1<=N<=100) segments(线段), please output the number of all intersections(交点). You should count repeatedly if M (M>2) segments intersect at the same point.
    Note: You can assume that two segments would not intersect at more than one point. 
     
    Input
    Input contains multiple test cases. Each test case contains a integer N (1=N<=100) in a line first, and then N lines follow. Each line describes one segment with four float values x1, y1, x2, y2 which are coordinates of the segment’s ending.  A test case starting with 0 terminates the input and this test case is not to be processed.
     
    Output
    For each case, print the number of intersections, and one line one case.
     
    Sample Input
    2 0.00 0.00 1.00 1.00 0.00 1.00 1.00 0.00 3 0.00 0.00 1.00 1.00 0.00 1.00 1.00 0.000 0.00 0.00 1.00 0.00 0
     
    Sample Output
    1 3
     
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    using namespace std;
    #define EPS 1e-8
    #define PI acos(-1.0)
    
    int dump(double x)
    {
        if(fabs(x)<EPS) return 0;
        return x<0?-1:1;
    }
    struct Point
    {
        double x,y;
        Point (){}
        Point (double x,double y):x(x),y(y){}
        Point operator + (const Point &p)const
        {
            return Point(x+p.x,y+p.y);
        }
        Point operator - (const Point &p)const
        {
            return Point(x-p.x,y-p.y);
        }
        double operator ^ (const Point &p)const
        {
            return x*p.y-y*p.x;
        }
        double operator * (const Point &p)const
        {
            return x*p.x+y*p.y;
        }
    };
    struct Line
    {
        Point s,e;
        Line (){}
        Line (Point s,Point e):s(s),e(e){}
    };
    bool SegInterSeg(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) &&
            dump((l2.s-l1.e)^(l1.s-l1.e))*dump((l2.e-l1.e)^(l1.s-l1.e))<=0 &&
            dump((l1.s-l2.e)^(l2.s-l2.e))*dump((l1.e-l2.e)^(l2.s-l2.e))<=0;
    }
    int main()
    {
        int i,j,n;
        Line l[1010];
        while(scanf("%d",&n),n)
        {
            for(i=1;i<=n;i++)
            {
                scanf("%lf%lf%lf%lf",&l[i].s.x,&l[i].s.y,&l[i].e.x,&l[i].e.y);
            }
            int cnt=0;
            for(i=1;i<=n;i++)
            {
                for(j=i+1;j<=n;j++)
                {
                    if(SegInterSeg(l[i],l[j])) cnt++;
                }
            }
            cout<<cnt<<endl;
        }
        return 0;
    }

    HDU 1147

    Pick-up sticks

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

    Total Submission(s): 2172    Accepted Submission(s): 800 

    Problem Description
    Stan has n sticks of various length. He throws them one at a time on the floor in a random way. After finishing throwing, Stan tries to find the top sticks, that is these sticks such that there is no stick on top of them. Stan has noticed that the last thrown stick is always on top but he wants to know all the sticks that are on top. Stan sticks are very, very thin such that their thickness can be neglected. 
     
    Input
    Input consists of a number of cases. The data for each case start with 1 ≤ n ≤ 100000, the number of sticks for this case. The following n lines contain four numbers each, these numbers are the planar coordinates of the endpoints of one stick. The sticks are listed in the order in which Stan has thrown them. You may assume that there are no more than 1000 top sticks. The input is ended by the case with n=0. This case should not be processed. 
     
    Output
    For each input case, print one line of output listing the top sticks in the format given in the sample. The top sticks should be listed in order in which they were thrown.  The picture to the right below illustrates the first case from input.
     
    Sample Input
    5 1 1 4 2 2 3 3 1 1 -2.0 8 4 1 4 8 2 3 3 6 -2.0 3 0 0 1 1 1 0 2 1 2 0 3 1 0
     
    Sample Output
    Top sticks: 2, 4, 5. Top sticks: 1, 2, 3.
     
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    using namespace std;
    #define EPS 1e-8
    #define N 100010
    
    int dump(double x)
    {
        if(fabs(x)<EPS) return 0;
        return x<0?-1:1;
    }
    struct Point
    {
        double x,y;
        Point (){}
        Point (double x,double y):x(x),y(y){}
        Point operator + (const Point &p)const
        {
            return Point(x+p.x,y+p.y);
        }
        Point operator - (const Point &p)const
        {
            return Point(x-p.x,y-p.y);
        }
        double operator ^ (const Point &p)const
        {
            return x*p.y-y*p.x;
        }
        double operator * (const Point &p)const
        {
            return x*p.x+y*p.y;
        }
    };
    struct Line
    {
        Point s,e;
        Line (){}
        Line (Point s,Point e):s(s),e(e){}
    };
    bool SegInterSeg(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) &&
            dump((l2.s-l1.e)^(l1.s-l1.e))*dump((l2.e-l1.e)^(l1.s-l1.e))<=0 &&
            dump((l1.s-l2.e)^(l2.s-l2.e))*dump((l1.e-l2.e)^(l2.s-l2.e))<=0;
    }
    
    int n,m;
    Line l[N];
    int vis[N];
    
    int main()
    {
        int i,j;
        while(scanf("%d",&n),n)
        {
            memset(vis,1,sizeof(vis));
            for(i=1;i<=n;i++)
            {
                scanf("%lf%lf%lf%lf",&l[i].s.x,&l[i].s.y,&l[i].e.x,&l[i].e.y);
            }
            for(i=1;i<=n;i++)
            {
                for(j=i+1;j<=n;j++)
                {
                    if(SegInterSeg(l[i],l[j]))
                    {
                        vis[i]=0;
                        break;
                    }
                }
            }
            printf("Top sticks: ");
            bool first=1;
            for(i=1;i<=n;i++)
            {
                if(vis[i])
                {
                    if(first)
                    {
                        first=0;
                        cout<<i;
                    }
                    else cout<<", "<<i;
                }
            }
            cout<<'.'<<endl;
        }
        return 0;
    }

    HDU 1558

    Segment set

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

    Total Submission(s): 3564    Accepted Submission(s): 1328 

    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
     
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    using namespace std;
    #define EPS 1e-8
    #define N 1010
    
    int dump(double x)
    {
        if(fabs(x)<EPS) return 0;
        return x<0?-1:1;
    }
    struct Point
    {
        double x,y;
        Point (){}
        Point (double x,double y):x(x),y(y){}
        Point operator + (const Point &p)const
        {
            return Point(x+p.x,y+p.y);
        }
        Point operator - (const Point &p)const
        {
            return Point(x-p.x,y-p.y);
        }
        double operator ^ (const Point &p)const
        {
            return x*p.y-y*p.x;
        }
        double operator * (const Point &p)const
        {
            return x*p.x+y*p.y;
        }
    };
    struct Line
    {
        Point s,e;
        Line (){}
        Line (Point s,Point e):s(s),e(e){}
    };
    bool SegInterSeg(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) &&
            dump((l2.s-l1.e)^(l1.s-l1.e))*dump((l2.e-l1.e)^(l1.s-l1.e))<=0 &&
            dump((l1.s-l2.e)^(l2.s-l2.e))*dump((l1.e-l2.e)^(l2.s-l2.e))<=0;
    }
    
    int n,m;
    int f[N];
    Line l[N];
    int sum[N];
    
    int Find(int x)
    { 
        return x==f[x]?x:Find(f[x]);
    }
    void un(int x,int y)
    {
        x=Find(x);
        y=Find(y);
        if(x>y) f[x]=y,sum[y]+=sum[x];
        if(x<y) f[y]=x,sum[x]+=sum[y];
    }
    int main()
    {
        int T,i,iCase=1;
        scanf("%d",&T);
        while(T--)
        {
            n=0;
            for(i=1;i<=1000;i++)
            {
                f[i]=i;
                sum[i]=1;
            }
            if(iCase!=1) printf("
    ");
            iCase++;
            scanf("%d",&m);
            while(m--)
            {
                char op;
                scanf(" %c",&op);
                if(op=='P')
                {
                    n++;
                    scanf("%lf%lf%lf%lf",&l[n].s.x,&l[n].s.y,&l[n].e.x,&l[n].e.y);
                    for(i=1;i<n;i++)
                    {
                        if(SegInterSeg(l[n],l[i]))
                        {
                            un(n,i);
                        }
                    }
                }
                else
                {
                    int x;
                    scanf("%d",&x);
                    x=Find(x);
                    printf("%d
    ",sum[x]);
                }
            }
        }
        return 0;
    }
    趁着还有梦想、将AC进行到底~~~by 452181625
  • 相关阅读:
    MySQL数据库的常用命令
    MySQL数据库的概念
    Linux磁盘管理
    linux账号与权限管理
    安装及管理程序
    vi编辑器+常用命令
    centos7下部署elasticsearch7.2集群--Elastic Stack之一
    打开virt-manager界面显示方格乱码
    Rabbitmq之修改日志和数据存放路径
    Rabbitmq之Memory
  • 原文地址:https://www.cnblogs.com/hate13/p/4142681.html
Copyright © 2011-2022 走看看