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

 

posted @ 2013-01-16 17:52  Griselda.  阅读(206)  评论(0编辑  收藏  举报