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;
}

浙公网安备 33010602011771号