P2449 [SDOI2005]矩形(矩形判重)题解

【题目链接】

link

【解题思路】

这道题目所求的是形成不同块的个数,其实就是求图的连通分量,那么我们就可以使用并查集算法,如矩形 x x x 和矩形 y y y 是重合的,并且处于不同一个集合那么我们就把矩形 x x x 和矩形 y y y 连接,最后我们只要记录有多少个集合就可以了。

这样子的做法,我们很容易就能够想到,但是问题在于如何判断两个矩形是否重合。

但是如果我们直接判断两个矩形是否重合,我们会发现比较难判断,那么我们可以把两个矩形没有重合的情况判断,剩下的就是重合的情况而了。

我们不重合有分为两种情况,
第一种情况:是两个矩形八竿子打不着一起,也就是矩形 x x x 在矩形 y y y 上下左右四个方向的时候。
第二种情况:这样个矩形出现了重边的情况,这样子在题目中也是不算重合的。

判断矩形重合的代码

bool check(Ger x,Ger y)
{
	//x矩形及y矩形
	//x1,y1代表横竖坐标
	if(x.x2<y.x1/*矩形x在矩形y的下方*/||y.x2<x.x1/*矩形x在矩形y的上方*/||x.y2<y.y1/*矩形x在矩形y的左方*/||y.y2<x.y1/*矩形x在矩形y的右方*/)return 0;
	if ((x.x1==y.x2||x.x2==y.x1)&&(x.y1==y.y2||x.y2==y.y1))/*角重合*/return 0;
	return 1;
}

【完整代码】

#include<bits/stdc++.h>
using namespace std;
int n,m;
int f[100010];
int sum=0;
struct Ger
{
	int x1,y1,x2,y2;
}G[100010];
int find(int x)
{
	if (f[x]==x)return x;
	return f[x]=find(f[x]);
}
void join(int x,int y)
{
	f[find(x)]=f[find(y)];
}
bool check(Ger x,Ger y)
{
	if(x.x2<y.x1||y.x2<x.x1||x.y2<y.y1||y.y2<x.y1)return 0;
	if ((x.x1==y.x2||x.x2==y.x1)&&(x.y1==y.y2||x.y2==y.y1))return 0;
	return 1;
}
int main()
{
	ios::sync_with_stdio(false);
	cin>>n;
	for (int i=1;i<=n;i++)	
		f[i]=i;
	for (int i=1;i<=n;i++)
		{
			cin>>G[i].x1>>G[i].y1>>G[i].x2>>G[i].y2;
			for (int j=1;j<i;j++)
			{
				if (check(G[i],G[j])&&find(f[i])!=find(f[j]))
					join(i,j);
			}
		}
	for (int i=1;i<=n;i++)
	{
		if (f[i]==i)
			sum++;
	}
	cout<<sum;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值