zoukankan      html  css  js  c++  java
  • [ACM] hdu Jack Straws

    Jack Straws

    Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
    Total Submission(s) : 5   Accepted Submission(s) : 2

    Font: Times New Roman | Verdana | Georgia

    Font Size:  

    Problem Description

    In the game of Jack Straws, a number of plastic or wooden "straws" are dumped on the table and players try to remove them one-by-one without disturbing the other straws. Here, we are only concerned with if various pairs of straws are connected by a path of touching straws. You will be given a list of the endpoints for some straws (as if they were dumped on a large piece of graph paper) and then will be asked if various pairs of straws are connected. Note that touching is connecting, but also two straws can be connected indirectly via other connected straws.

    Input

    Input consist multiple case,each case consists of multiple lines. The first line will be an integer n (1 < n < 13) giving the number of straws on the table. Each of the next n lines contain 4 positive integers,x1,y1,x2 and y2, giving the coordinates, (x1,y1),(x2,y2) of the endpoints of a single straw. All coordinates will be less than 100. (Note that the straws will be of varying lengths.) The first straw entered will be known as straw #1, the second as straw #2, and so on. The remaining lines of the current case(except for the final line) will each contain two positive integers, a and b, both between 1 and n, inclusive. You are to determine if straw a can be connected to straw b. When a = 0 = b, the current case is terminated. 

    When n=0,the input is terminated. 

    There will be no illegal input and there are no zero-length straws.

    Output

    You should generate a line of output for each line containing a pair a and b, except the final line where a = 0 = b. The line should say simply "CONNECTED", if straw a is connected to straw b, or "NOT CONNECTED", if straw a is not connected to straw b. For our purposes, a straw is considered connected to itself.

    Sample Input

    7
    1 6 3 3 
    4 6 4 9 
    4 5 6 7 
    1 4 3 5 
    3 5 5 5 
    5 2 6 3 
    5 4 7 2 
    1 4 
    1 6 
    3 3 
    6 7 
    2 3 
    1 3 
    0 0
    
    2
    0 2 0 0
    0 0 0 1
    1 1
    2 2
    1 2
    0 0
    
    0

    Sample Output

    CONNECTED 
    NOT CONNECTED 
    CONNECTED 
    CONNECTED 
    NOT CONNECTED 
    CONNECTED
    CONNECTED
    CONNECTED
    CONNECTED

    Author

    YTlearner

    Source

    East Central North America 1994


    解题思路:

    题目关键点是判断两线段是否相交和并查集的使用。两个线段可以直接相交也可以通过其它线段间接相交,题目中的意思是不管两个线段是直接还是间接相交,都输出CONNECTED ,否则输出 NOT CONNECTED。并查集的使用是把所有相交的线段放在同一个集合里面(包括直接相交和间接相交),查询的时候,如果两个线段在同一集合(有相同的根节点)就是相交的情况。

    代码:

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    struct point//构造点
    {
        int x,y;
    };
    struct line//构造线段
    {
        point a,b;
    };
    
    double multi(point p1,point p2,point p0)//矩形面积
    {
        return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
    }
    
    bool intersect(line u,line v)//判断两线段是否相交
    {
     return( (max(u.a.x,u.b.x)>=min(v.a.x,v.b.x))&&
            (max(v.a.x,v.b.x)>=min(u.a.x,u.b.x))&&
            (max(u.a.y,u.b.y)>=min(v.a.y,v.b.y))&&
            (max(v.a.y,v.b.y)>=min(u.a.y,u.b.y))&&
            (multi(v.a,u.b,u.a)*multi(u.b,v.b,u.a)>=0)&&
            (multi(u.a,v.b,v.a)*multi(v.b,u.b,v.a)>=0));
    }
    
    int parent[14];//父节点
    int rank[14];//树高
    int n;
    line lin[14];//线段数
    
    void init(int n)//初始化集合,每条线段都是一个独立的集合,树高全部为0
    {
        for(int i=1;i<=n;i++)
           {
               parent[i]=i;
               rank[i]=0;
           }
    }
    
    int find(int x)//找根节点
    {
        return parent[x]==x?x:find(parent[x]);
    }
    
    void unite(int x,int y)//把两个集合合并,树高(rank)小的向大的那边合并。
    {
        x=find(x);
        y=find(y);
        if(x==y)return;
        if(rank[x]<rank[y])
            parent[x]=y;
        else
        {
            parent[y]=x;
            if(rank[x]==rank[y])
                rank[x]++;
        }
    
    }
    
    bool same(int x,int y)//判断两条线段是否有相同的根节点,也就是判断是否属于同一集合,同一集合的线段都相连(直接相连和间接相连)
    {
        return find(x)==find(y);
    }
    int main()
    {
        while(cin>>n&&n)
        {
            for(int i=1;i<=n;i++)
            {
                cin>>lin[i].a.x>>lin[i].a.y>>lin[i].b.x>>lin[i].b.y;
            }
            init(n);
            for(int i=1;i<=n;i++)//集合合并过程
                for(int j=i+1;j<=n;j++)
            {
                if(intersect(lin[i],lin[j]))//如果第i条线段和第j条线段相交
                    unite(i,j);
            }
            int l1,l2;
            while(cin>>l1>>l2&&l1&&l2)
            {
                if(same(l1,l2))
                    cout<<"CONNECTED"<<endl;
                else
                    cout<<"NOT CONNECTED"<<endl;
            }
        }
        return 0;
    }
    

    运行:


  • 相关阅读:
    JAVA中HashMap相关知识的总结(一)
    linux进阶之路(三):vi/vim编辑器
    linux进阶之路(二):linux文件目录
    linux进阶之路(一):linux入门
    linux:lrzsz安装
    一:阿里云服务器使用及后台环境搭建
    第二篇:线程七种状态
    Git log
    redis3.0 集群实战3
    详解Linux chgrp和chown命令的用法
  • 原文地址:https://www.cnblogs.com/sr1993/p/3697794.html
Copyright © 2011-2022 走看看