• SGU


    上题目

    Walls

      ime Limit:1500MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

    Description

    People of country T-land lived on the big plain many years ago. It is happened so that they started to quarrel, so they began to build walls to separate from each other.
    One day they realized that walls surround some part of the country. Your task is to determine which wall was build first to surround a part of the T-land.

    Input

    The first line of input contains one number M (1<=M<=200000) - number of walls. Each of the following M lines contains four integer numbers: Cartesian coordinates of two ends of each wall. Walls are rectilinear segments with positive length, two walls can cross only by ends, and walls can't coincide. All coordinates do not exceed 10^9 by its absolute values.

    Output

    Write the answer in the single line of output. If all the walls leave the territory opened, write 0.

    Sample Input


    Input
    4
    0 0 1 0
    0 1 0 0
    1 0 0 1
    2 2 5 7

    Output
    3
     
      其实看懂了题目就是一道水的并查集。题意是给你最多200000条线段,不会重复,只会有可能端点相连或者没有任何接触。问你第几条线段出现的时候会出现封闭的图形,如果没有出现封闭的图形,输出0。
      解法就是将线段上的点并入集合中,如果出现一条线段的两个端点在合并前就已经在同一个集合中的时候就说明已经围成封闭的图形了。
      一开始没有看清题意,以为不可以出现同样的线段,但可以相交,于是就写了一段判断线段相交的代码,结果这段代码不可以判断负数,wa了好几次。后来又重写了2次,都是以线段为单位构成并查集,但是都wa了。其实一开始有想过以单个点为单位构成集合,可是当时没有想透彻,于是没有实现。同时这里我使用了map来处理,虽然速度上可能慢了一点,但是编程复杂度小了很多。
     
    上代码:
     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <map>
     4 #include <utility>
     5 #define MAX 400000+10
     6 using namespace std;
     7 
     8 typedef pair<int,int> point;
     9 int p[MAX],rank[MAX],tot;
    10 map<point,int> r;
    11 
    12 int findset(int x)
    13 {
    14     return x==p[x] ? x : findset(p[x]);
    15 }
    16 
    17 bool unionset(int x,int y)
    18 {
    19     x=findset(x);
    20     y=findset(y);
    21     if(x==y) return 1;
    22     if(rank[x]>rank[y])
    23     {
    24         p[y]=x;
    25     }
    26     else
    27     {
    28         p[x]=y;
    29         if(rank[x]==rank[y]) rank[y]++;
    30     }
    31     return 0;
    32 }
    33 
    34 int main()
    35 {
    36     int i,j,m;
    37     point a,b;
    38     //freopen("data.txt","r",stdin);
    39     memset(p,-1,sizeof(p));
    40     memset(rank,0,sizeof(rank));
    41     r.clear();
    42     tot=0;
    43     scanf("%d",&m);
    44     for(i=1;i<=m;i++)
    45     {
    46         scanf("%d %d",&a.first,&a.second);
    47         scanf("%d %d",&b.first,&b.second);
    48         if(r.count(a)<=0) {r[a]=tot; p[tot]=tot; tot++;}
    49         if(r.count(b)<=0) {r[b]=tot; p[tot]=tot; tot++;}
    50         if(unionset(r[a],r[b])) break;
    51     }
    52     for(j=i+1;j<=m;j++)
    53     {
    54         scanf("%d %d",&a.first,&a.second);
    55         scanf("%d %d",&b.first,&b.second);
    56     }
    57     if(i<=m) printf("%d
    ",i);
    58     else printf("0
    ");
    59     return 0;
    60 }
    walls
  • 相关阅读:
    (CVE-2020-1938)Apache Tomcat AJP文件包含漏洞复现
    Linux rm 反向删除/排除制定文件(夹)
    Linux下JDK安装及配置 (tar.gz版)
    Linux内核源码分析 -- 同步原语 -- 互斥锁 mutex(未完成)
    Linux内核源码分析 -- 同步原语 -- 自旋锁 spinlock
    Linux内核源码分析 -- 同步原语 -- 信号量 semaphore
    Linux 内核源码分析 -- getuid, geteuid
    Linux 内核源码分析 -- chroot
    手动模拟 Linux 内核 mmu 内存寻址
    glibc-free-_int_free
  • 原文地址:https://www.cnblogs.com/sineatos/p/3197070.html
Copyright © 2020-2023  润新知