Hlg 1619 只有矩形.cpp【并查集】

前序:这题是2011年亚洲赛区的弱化版题目..原题(ZOJ 3544)是画三角形和圆形还有矩形

题意:

在一个屏幕上画q个带颜色的矩形

问9种颜色各占了几个格子

 

输入数据给出屏幕的长n(n <= 200) 宽m(m <= 50000) 和 q个矩形(q <= 50000)

接下来q行给出每个矩形的起始位置和长、宽以及矩形的颜色

最后输出9个颜色各占几个格子

 

思路:

先读入数据..

然后从最后一个矩形开始处理..

因为越后画的矩形肯定越靠前..即最后画的矩形肯定完全没有被覆盖..

然后我们把最后一个矩形覆盖的地方标记出来..

再处理倒数第2个矩形........................................

如果暴力处理肯定会超时..m太大了..

所以可以用并查集..

pre[x][y] = yy表示在x行..从y列到yy列都是被合并成一种颜色了的...

一开始所有的pre[x][y] = y表示当前行没有被合并..当对当前行y到某一行yy都涂上一个颜色的时候..就标记pre[x][y] = yy

这样下次遍历的时候如果发现pre[x][y] = yy;则从这一行开始到yy都可以不看..因为y~yy会被后来画的矩形给覆盖掉..

这样就节省了很多时间..

 

Tips:

应该把屏幕看成200个50000列

而不是50000个200行..否则遍历50000列的时候依然会超时..

 

P.S..我很不理解的是为什么我对行和列都用并查集来优化居然会超时..

这让我很不解..

附上tle代码..<这不科学..= =>

 

Code:

AC代码
 1 #include <stdio.h>

 2 #include <cstring>

 3 using namespace std;

 4 

 5 int pre[210][50010];

 6 int find(int x, int y)

 7 {

 8     return pre[x][y] == y?y:(pre[x][y] = find(x, pre[x][y]));

 9 }

10 

11 struct Inf

12 {

13     int xc;

14     int yc;

15     int l;

16     int w;

17     int c;

18 }inf[50010];

19 

20 int cnt[10];

21 int main()

22 {

23     int n, m, q;

24     while(EOF != scanf("%d %d %d", &n, &m, &q)) {

25         for(int i = 0; i <= n+1; ++i)

26         for(int j = 0; j <= m+1; ++j)

27             pre[i][j] = j;

28         for(int i = 0; i < 10; ++i)

29         cnt[i] = 0;

30 

31         for(int i = 0; i < q; ++i)

32         scanf("%d %d %d %d %d", &inf[i].xc, &inf[i].yc, &inf[i].l, &inf[i].w, &inf[i].c);

33 

34         for(int i = q-1; i >= 0; --i) {

35             for(int j = inf[i].xc; j <= inf[i].xc+inf[i].l-1; ++j) {

36                 int fy = find(j, inf[i].yc+inf[i].w);

37                 for(int k = inf[i].yc; k <= inf[i].yc+inf[i].w-1;) {

38                     int fk = find(j, k);

39                     if(fk != k) k = fk;

40                     else {

41                         cnt[inf[i].c]++;

42                         pre[j][k] = fy;

43                         k++;

44                     }

45                 }

46             }

47         }

48 

49         for(int i = 1; i < 10; ++i)

50         printf("%d%c", cnt[i], i==9?'\n':' ');

51     }

52     return 0;

53 }
Tle 代码
 1 #include <stdio.h>

 2 #include <cstring>

 3 using namespace std;

 4 

 5 struct Inf

 6 {

 7     int xc;

 8     int yc;

 9     int l;

10     int w;

11     int c;

12 }inf[50010];

13 

14 int prex[210][5010], prey[210][5010];

15 int findx(int x, int y)

16 {

17     return prex[x][y] == x?x:(prex[x][y] = findx(prex[x][y], y));

18 }

19 

20 int findy(int x, int y)

21 {

22     return prey[x][y] == y?y:(prey[x][y] = findy(x, prey[x][y]));

23 }

24 

25 

26 int main()

27 {

28     int xc, yc, l, w, c;

29     int n, m, q;

30     int fy, fx, fj, fk;

31     int cnt[10];

32     while(EOF != scanf("%d %d %d", &n, &m, &q)) {

33         for(int i = 0; i <= n+1; ++i)

34         for(int j = 0; j <= m+1; ++j)

35         prex[i][j] = i, prey[i][j] = j;

36 

37         memset(cnt, 0, sizeof(cnt));

38 

39         for(int i = 0; i < q; ++i)

40             scanf("%d %d %d %d %d", &inf[i].xc, &inf[i].yc, &inf[i].l, &inf[i].w, &inf[i].c);

41         for(int i = q-1; i >= 0; --i) {

42             for(int j = inf[i].yc; j <= inf[i].yc+inf[i].w-1;) {

43                 for(int k = inf[i].xc; k<= inf[i].xc+inf[i].l-1;) {

44                     fy = findy(k, inf[i].yc+inf[i].w);

45                     fj = findy(k, j);

46                     if(j != fj) {

47                         j = fj;

48                         break;

49                     }

50                     else {

51                         fx = findx(inf[i].xc+inf[i].l, j);

52                         fk = findx(k, j);

53                         if(k != fk) k = fk;

54                         else {

55                             k++;

56                             cnt[inf[i].c] += 1;

57                             prex[fk][fj] = fx;

58                         }

59                     }

60                     prey[fk][fj] = fy;

61                 }

62                 if(j == fj)

63                     j++;

64             }

65         }

66 

67         for(int i = 1; i < 10; ++i)

68         printf("%d%c", cnt[i], i == 9?'\n':' ');

69     }

70     return 0;

71 }

 

扩展:一个简单的类似并查集应用..

Hlg 1041 http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1041

链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1619

 

你可能感兴趣的:(并查集)