• HLG 1507 水神的栅栏【判断线段相交+并查集】


    Description

    水神在赚了一笔钱之后,购买了一座庄园,做起了农场主,水神的农场都是靠栅栏围墙来分成很多部分并且围成外面的围墙的,但是最近一段时间,水神的庄园遭到了神兽的袭击,神兽撞破了很多处栅栏,这让水神非常苦恼,为了弄清楚自己的栅栏还有哪些地方时连着的,水神画了一张平面图,每一段栅栏在图上表示成一个线段,这些线段有的会相交,有的不会。

    水神需要知道两段栅栏是否可以连起来。

    Input

    有多组输入数据,每组数据:

    第一行一个整数n表示水神农场的栅栏的个数(n<13)

    接下来n行,每行四个整数x1,y1,x2,y2分别表示栅栏的两个端点坐标

    然后下面若干行是对栅栏连接情况的询问,每行两个整数a,b表示水神想知道,栅栏a和栅栏b是否可以连起来。询问以0 0结束。

    n=0时输入结束

    Output

    对于每次询问,如果栅栏a和b可以连起来,输出 CONNECTED,否则输出:NOT CONNECTED.

    Sample Input

    2

    0 2 0 0

    0 0 0 1

    1 1

    2 2

    1 2

    0 0

    2

    0 2 0 0

    1 0 2 0

    1 2

    0 0

    0

    Sample Output

    CONNECTED

    CONNECTED

    CONNECTED

    NOT CONNECTED

    思路:如果两条线段相交,则他们之间相连,两个几何并在一起。

    代码如下:

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    using namespace std; 
    struct point 
    {
        int x1, y1, x2, y2;
    };
    int f[20]; 
    int find(int x)
    {
        return x==f[x]?f[x]:f[x]=find(f[x]);
    }
    int mul(int ax, int ay, int bx, int by, int cx, int cy)
    {
        return (ax-cx)*(by-cy)-(bx-cx)*(ay-cy);
    } 
    int main()
    {
        int i, j, n, qx, qy;
        while(scanf("%d", &n)!=EOF)
        {
            if(n==0)    break;
            for(i=0; i<=15; i++)
                f[i]=i;
            point p[20]; 
            for(i=1; i<=n; i++)
                scanf("%d%d%d%d", &p[i].x1, &p[i].y1, &p[i].x2, &p[i].y2);
            for(i=1; i<=n; i++)
                for(j=i+1; j<=n; j++)
                {
                    if((max(p[i].x1, p[i].x2)>=min(p[j].x1, p[j].x2)) 
                        &&(max(p[j].x1, p[j].x2)>=min(p[i].x1, p[i].x2)) 
                        &&(max(p[i].y1, p[i].y2)>=min(p[j].y1, p[j].y2))
                        &&(max(p[j].y1, p[j].y2)>=min(p[i].y1, p[i].y2)) 
                        &&(mul(p[j].x1, p[j].y1, p[i].x2, p[i].y2, p[i].x1, p[i].y1)
                            *mul(p[i].x2, p[i].y2, p[j].x2, p[j].y2, p[i].x1, p[i].y1)>=0)
                        &&(mul(p[i].x1, p[i].y1, p[j].x2, p[j].y2, p[j].x1, p[j].y1)
                            *mul(p[j].x2, p[j].y2, p[i].x2, p[i].y2, p[j].x1, p[j].y1)>=0))
                    {
                        int xx=find(i);      int yy=find(j);
                        if(xx<yy) 
                            f[xx]=yy;
                        else
                            f[yy]=xx; 
                    }
                }
            while(1)
            {
                scanf("%d%d", &qx, &qy);
                if(qx==0&&qy==0)    break;
                int xx=find(qx);    int yy=find(qy);
                if(xx==yy)
                    printf("CONNECTED\n");
                else
                    printf("NOT CONNECTED\n");
            }
        }
    }
  • 相关阅读:
    F. Journey
    D. Divide
    C. Counting Pair
    A. A Big Dinner
    E
    D -Sale
    第十三课 历史记录画笔工具
    第十二课 文字工具
    第十一课 模糊工具、海绵工具、仿制图章工具
    第十课 切片工具 修复画笔工具 修补工具 颜色替换工具
  • 原文地址:https://www.cnblogs.com/Hilda/p/2620852.html
Copyright © 2020-2023  润新知