zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    电商系统服务拆分实战
    打通电商多模式支持的“任督二脉”
    win10 home安装docker快速攻略
    如何深入理解一套MQ消息中间件
    自带win10的笔记本电脑如何装win7
    《大数据日知录:架构与算法》读书笔记(多图)
    一个典型的后台软件系统的设计复盘——(三)打通任督二脉-context
    一个典型的后台软件系统的设计复盘——(二)如何id一个事物
    dubbox源码分析(一)-服务的启动与初始化
    svn老鸟转用git必须理解的概念
  • 原文地址:https://www.cnblogs.com/Griselda/p/2863169.html
Copyright © 2011-2022 走看看