JZOJ 1956. 矩形

题目

Description

现在我们在一个平面上画了n个矩形。每一个矩形的两边都与坐标轴相平行,且矩形定点的坐标均为整数。现我们定义满足如下性质的图形为一个块:
 每一个矩形都是一个块;
 如果两个块有一段公共的部分,那么这两个块就会形成一个新的块,否则这两个块就是不同的。

 示例:
图1中的矩形形成了两个不同的块。
图2中的矩形形成了一个块。

任务:
请写一个程序:
 从文本文件PRO.IN中读入各个矩形的顶点坐标;
 找出这些矩形中不同的块的数目;
 把结果输出到文本文件PRO.OUT中。
 

Input

       在输入文件PRO.IN的第一行又一个整数n,1 <= n <=7000,表示矩形的个数。接下来的n行描述矩形的顶点,每个矩形用四个数来描述:左下顶点坐标(x,y)与右上顶点坐标(x,y)。每个矩形的坐标都是不超过10000的非负整数。

Output

输出唯一的一个整数——这些矩形所形成的不同的块的数目。
 

Sample Input

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

Sample Output

2
 

Data Constraint

数据规模
对于60%的数据,有N<=80
对于100%的数据如题目。

分析

 

  • 并查集一定要打 f[x]=find(x);
  • 主要是判断是否相交哪里要细节一点

 

代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
struct sb
{
    int x,xx,y,yy;
}a[7001];
int fa[7001],r[7001];
int find(int x)
{return fa[x]==x?x:fa[x]=find(fa[x]);}
int jud(int d,int dd)
{
  int xf1=a[d].x,yf1=a[d].y,xf2=a[d].xx,yf2=a[d].yy;
  int xl1=a[dd].x,yl1=a[dd].y,xl2=a[dd].xx,yl2=a[dd].yy;
  if((xl1<xf1&&xl2<xf1)||(xl1>xf2&&xl2>xf2)||(yl1<yf1&&yl2<yf1)||(yl1>yf2&&yl2>yf2)) return 0;
  if((xl1==xf2&&yl1==yf2)||(xl1==xf2&&yl2==yf1)||(xl2==xf1&&yl1==yf2)||(xl2==xf1&&yl2==yf1)) return 0;
  return 1;
}
int t[7001];
int main()
{
    freopen("pro.in","r",stdin);
    freopen("pro.out","w",stdout);
    int n;
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].xx,&a[i].yy);
    for (int i=1;i<=n;i++) fa[i]=i,r[i]=1;
    for (int i=1;i<n;i++) 
      for (int j=i+1;j<=n;j++)
      {
          int c=jud(i,j);
          if (c==1)
          {
               int u=find(i); 
               int v=find(j);
               if (u!=v)
               {
                    if (r[u]<=r[v])
                    {
                       fa[v]=u;
                       r[u]+=r[v];
                }
                else 
                {
                    fa[u]=v;
                       r[v]+=r[u];
                }
             }
                 
          }
      }
    int ans=0;
    for (int i=1;i<=n;i++)
    {
        int u=find(i);
        if (t[u]==0)
        {
            t[u]=1;
            ans++;
        }
    }
    cout<<ans;
    return 0;
}

 

 

posted @ 2019-11-06 15:41  Melted_czj  阅读(134)  评论(0编辑  收藏  举报
body { background-color:whitesmoke; } // 修改背景颜色为半透明 #home,#sideBarMain>div,#blog-sidecolumn>div>div,.catListView{ background-color:rgba(255,255,255,0); } // 修改其他边框的颜色