SDNU 1016.矩形合并 并查集

来源:互联网 发布:卡盟js代码申请 编辑:程序博客网 时间:2024/05/29 07:30

1016.矩形合并


Time Limit: 1000 MS    Memory Limit: 32768 KB

Total Submission(s): 242    Accepted Submission(s): 49


Description

平面上有n个矩形,给定每个矩形的左下角坐标和右上角坐标。如果把重合的矩形合并成一个图形,则经过合并之后,还剩多少个图形?


Input
第1行:一个整数n(1 <= n <= 100),表示矩形的数量。

第2至第n+1行:每行有4个整数,第i 行中的4个数字分别表示编号为i-1的矩形的左下角x、y坐标与右上角x、y坐标。


Output

合并后剩余的图形数。


Sample Input

3
0 0 2 2
1 1 4 4
4 4 5 5

Sample Output

2

Hint

相邻不重合的图形不合并


    首先考虑一下这个矩形什么情况下合并,因为相邻不重合的图形不合并,所以我直接判断是否不重合,如果不重合的话就一定是重合的。判断的方式就是,已知一个矩形A的左下角和右上角,然后用矩形B的左下角和矩形A的右上角进行比较,如果B的左下角在A右上角的上面或右边的话,一定不重合。以同样的方法再处理B的右下角,这样就能判断出来是否重合了。

    画个图来表示的话:


    如果下一个图形的左下角在红色区域就一定不重合,如果下一个图形的右下角再黑色区域就一定不重合,其余的全部判断为重合。
    然后是进行记录,输出重合后会剩余几个图形,表示一开始我是用一个数组来储存的,一开始全初始化为1,然后如果重合后面图形变为0,最后数有多少个1即可。不过这样的话
3
0 0 2 2
2 2 4 4
0 0 4 4
这一组数据过不了,然后旁边队友说用并查集来做。好吧,其实之前一直觉得并查集没必要记,之前几道并查集的题我都直接用自己思路做出来了......所以一直把他忽略掉了,结果这次= =改了并查集之后过了,好吧,原谅我之前把你无视掉了_(:зゝ∠)_
    下面AC代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;bool vis[105];int pre[1005];struct mar{     int lx,ly;     int rx,ry;};mar m[105];int goal(mar a,mar b){     if(a.lx>=b.rx||a.ly>=b.ry)          return 0;     if(a.rx<=b.lx||a.ry<=b.ly)          return 0;     return 1;}int Find(int x){     int r=x;     while(r!=pre[r])          r=pre[r];     int i=x,j;     while(pre[i]!=r)     {          j=pre[i];          pre[i]=r;          i=j;     }     return r;}int mix(int x,int y){     int fx=Find(x),fy=Find(y);     if(fx!=fy)     {          pre[fy]=fx;     }     return 0;}int main(){     int n;     int i,j;     int ans;     while(scanf("%d",&n)!=EOF)     {          ans=0;          memset(vis,0,sizeof(vis));          memset(m,0,sizeof(m));          for(i=1;i<=n;i++)          {               pre[i]=i;               scanf("%d%d%d%d",&m[i].lx,&m[i].ly,&m[i].rx,&m[i].ry);          }          for(i=1;i<=n;i++)          {               for(j=i+1;j<=n;j++)               {                    if(goal(m[i],m[j])==1)                         mix(i,j);               }          }          for(i=1;i<=n;i++)          {               vis[Find(i)]=1;          }          for(i=1;i<=n;i++)          {               if(vis[i]==1)                    ans++;          }          cout<<ans<<endl;     }     return 0;}




0 0
原创粉丝点击