SDNU1016矩形合并(并查集)

几点教训:(1)将数据输入完成后再进行合并(2)两个矩形有交点的函数如果用必然有一个点的坐标在另一个矩形内这个原理来写,一共有8种情况,不能遗漏,下面是AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=105;
struct node
{
    int x1;
    int x2;
    int y1;
    int y2;
    int pre;
} p[maxn];
int vis[maxn];
int n,cnt;
void init()
{
    for(int i=0; i<=n; i++)
        p[i].pre=i;
    memset(vis,0,sizeof(vis));
    cnt=0;
}
int finds(int x)
{
    if(x==p[x].pre)
        return x;
    p[x].pre=finds(p[x].pre);
    return p[x].pre;
}
void unions(int a,int b)
{
    if(a==n+1||b==n+1)
        return;
    int x=finds(a);
    int y=finds(b);
    if(x==y);
    else
    {
        p[x].pre=y;
    }
}
bool judge(node a,node b)
{
    ///a.x1<a.x2;a.y1<a.y2
    if(a.x1<b.x1&&b.x1<a.x2&&a.y1<b.y1&&b.y1<a.y2)
        return true;
    if(a.x1<b.x2&&b.x2<a.x2&&a.y1<b.y2&&b.y2<a.y2)
        return true;
    if(b.x1<a.x1&&a.x1<b.x2&&b.y1<a.y1&&a.y1<b.y2)
        return true;
    if(b.x1<a.x2&&a.x2<b.x2&&b.y1<a.y2&&a.y2<b.y2)
        return true;
    if(a.x1<b.x1&&b.x1<a.x2&&a.y1<b.y2&&b.y2<a.y2)
        return true;
    if(a.x1<b.x2&&b.x2<a.x2&&a.y1<b.y1&&b.y1<a.y2)
        return true;
    if(b.x1<a.x1&&a.x1<b.x2&&b.y1<a.y2&&a.y2<b.y2)
        return true;
    if(b.x1<a.x2&&a.x2<b.x2&&b.y1<a.y1&&a.y1<b.y2)
        return true;
    if(a.x1==b.x1&&a.x2==b.x2&&a.y1==b.y1&&a.y2==b.y2)
        return true;
    return false;
}
int main()
{
    while(~scanf("%d",&n))
    {
        init();
        for(int i=1; i<=n; i++) ///左下角坐标和右上角坐标
        {
            scanf("%d%d%d%d",&p[i].x1,&p[i].y1,&p[i].x2,&p[i].y2);
        }
        //输入完数据在进行查找和合并
        for(int i=1; i<=n; i++)
            for(int j=i+1; j<=n; j++)
                if(judge(p[j],p[i]))
                    unions(j,i);
        for(int i=1; i<=n; i++)
            vis[finds(i)]=1;//看看有多少根节点
        for(int i=1; i<=n; i++)
            if(vis[i])
                cnt++;
        printf("%d\n",cnt);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41658955/article/details/81394629