• CodeForces 650C Table Compression


    题目链接: http://codeforces.com/problemset/problem/650/C

    ---------------------------------------------------------------------------------------------------------

    首先要知道的是这题原本相同的数最后是可以不同的

    然后主要是要考虑到$Z$字形的数据 ($a$代表某相同数字 $x$代表其他数字)

    $aax$

    $xaa$

    这种情况下第一行第一个和第二行第三个是必须相同的

    如果只是对行和列进行简单的十字型的判断的话这两个位置最终的数字很有可能不同

    所以我们要对行和列的当前最大数的最小值进行维护 然后就是写一个并查集了

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cmath>
     4 #include <algorithm>
     5 #include <vector>
     6 using namespace std;
     7 const int N = 1e6 + 10;
     8 vector <int> a[N], b[N];
     9 int s[N], num[N << 1], fa[N];
    10 int n, m, len, ans;
    11 int findf(int x)
    12 {
    13     if(fa[x] != x)
    14         fa[x] = findf(fa[x]);
    15     return fa[x];
    16 }
    17 void merge(int x, int y)
    18 {
    19     int tx = findf(x), ty = findf(y);
    20     if(tx != ty)
    21     {
    22         if(num[tx] >= num[ty])
    23             fa[ty] = tx;
    24         else
    25             fa[tx] = ty;
    26     }
    27 }
    28 int main()
    29 {
    30     int x, y;
    31     scanf("%d%d", &n, &m);
    32     for(int i = 0; i < n; ++i)
    33         for(int j = 0; j < m; ++j)
    34         {
    35             scanf("%d", &x);
    36             a[i].push_back(x);
    37             s[len++] = x;
    38         }
    39     sort(s, s + len);
    40     len = unique(s, s + len) - s;
    41     for(int i = 0; i < n; ++i)
    42         for(int j = 0; j < m; ++j)
    43         {
    44             a[i][j] = lower_bound(s, s + len, a[i][j]) - s;
    45             b[a[i][j]].push_back(i * m + j);
    46         }
    47     for(int i = 0; i < n + m; ++i)
    48         fa[i] = i;
    49     for(int i = 0; i < len; ++i)
    50     {
    51         for(int j = 0, sz = b[i].size(); j < sz; ++j)
    52         {
    53             x = b[i][j] / m;
    54             y = b[i][j] % m;
    55             merge(x, n + y);
    56         }
    57         for(int j = 0, sz = b[i].size(); j < sz; ++j)
    58         {
    59             x = b[i][j] / m;
    60             y = b[i][j] % m;
    61             a[x][y] = num[findf(x)] + 1;
    62         }
    63         for(int j = 0, sz = b[i].size(); j < sz; ++j)
    64         {
    65             x = b[i][j] / m;
    66             y = b[i][j] % m;
    67             num[x] = max(num[x], a[x][y]);
    68             num[n + y] = max(num[n + y], a[x][y]);
    69             fa[x] = x;
    70             fa[n + y] = n + y;
    71         }
    72     }
    73     for(int i = 0; i < n; ++i)
    74         for(int j = 0; j < m; ++j)
    75             printf("%d%c", a[i][j], (j == m - 1 ? '
    ' : ' '));
    76     return 0;
    77 }
  • 相关阅读:
    提高电脑运行效率
    Android_实验小心得_持续补充中......
    LNMP环境搭建wordpress
    php安装
    mysql、MariaDB(yum)
    Nginx配置(yum)
    httpd配置(yum)
    jumpserver环境搭建
    命令
    vsftpd
  • 原文地址:https://www.cnblogs.com/sagitta/p/5252502.html
Copyright © 2020-2023  润新知