DGZX1526 - 矩形

矩形数目最多是7000,而本题时间限制是2秒,意味着即使用O(n2)级别的算法,也可以不超时。

两重循环将矩形两两比较,如果出现重叠,就合并两个矩形,合并操作就用到并查集。

关键是如何判断两个矩形重叠。

#include <stdio.h>

typedef int POS;
const int maxn = 7000;
int n, ans;
int pos[maxn][4];// left bottom right top x y
int tree[maxn], rank[maxn];

bool judge(POS i, POS j)
{
	if (pos[i][0]<=pos[j][0] && pos[j][0]<=pos[i][2] && pos[i][1]<pos[j][3] && pos[i][3]>pos[j][1])
		return true;
	if (pos[j][0]<=pos[i][0] && pos[i][0]<=pos[j][2] && pos[j][1]<pos[i][3] && pos[j][3]>pos[i][1])
		return true;
	if (pos[i][1]<=pos[j][1] && pos[j][1]<=pos[i][3] && pos[i][0]<pos[j][2] && pos[i][2]>pos[j][0])
		return true;
	if (pos[j][1]<=pos[i][1] && pos[i][1]<=pos[j][3] && pos[j][0]<pos[i][2] && pos[j][2]>pos[i][0])
		return true;
	return false;
}

void init()
{
	int i;
	for (i=0; i<n; i++)
	{
		tree[i] = i;
		rank[i] = 1;
	}
}

POS find(POS x)
{
	POS t = x;
	while (tree[t]!=t)
		t = tree[t];
	POS p = x;
	while (tree[p]!=p)
	{
		p = tree[p];
		tree[x] = t;
		x = p;
	}
	return t;
}

void merge(POS a, POS b)
{
	POS fa = find(a);
	POS fb = find(b);
	if (fa!=fb)
		tree[fa] = fb;
}

int main()
{
	POS i, j;
	scanf("%d", &n);
	for (i=0; i<n; i++)
		scanf("%d%d%d%d", &pos[i][0], &pos[i][1], &pos[i][2], &pos[i][3]);
	init();
	for (i=0; i<n; i++)
	{
		for (j=i+1; j<n; j++)
		{
			if (judge(i, j))
				merge(i, j);
		}
	}
	for (i=0; i<n; i++)
	{
		if (tree[i]==i)
			ans++;
	}
	printf("%d\n", ans);
	return 0;
}

 

posted @ 2013-12-20 16:07  莞中OI  阅读(179)  评论(0)    收藏  举报