• 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 }
  • 相关阅读:
    vim编辑器
    linux常用的命令解释
    克隆虚拟机及本地仓库的搭建
    创建windows系统下的虚拟机
    创建linux系统下的虚拟机
    drf频率组件
    django中过滤 搜索 排序
    drf分页
    js回顾
    数据类型
  • 原文地址:https://www.cnblogs.com/sagitta/p/5252502.html
Copyright © 2020-2023  润新知