nq1s788

Сжатие

Nov 2nd, 2025
633
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.20 KB | None | 0 0
  1. Очень легко привести входные данные в несжатый вид (входные данные были даны в сжатом формате для того, чтобы сделать ограничения больше, но при этом менее зависимыми от времени на чтение данных).
  2.  
  3. Авторское решение выглядит следующим образом:
  4.  
  5. Пусть 𝑥
  6.  — ответ на задачу, и изначально он равен 𝑛
  7. . Переберем все строки матрицы и посчитаем длины максимальных по включению отрезков состоящих только из нулей или только из единиц. Пусть длина текущего отрезка равна 𝑙𝑒𝑛
  8. . Тогда присвоим 𝑥:=𝑔𝑐𝑑(𝑥,𝑙𝑒𝑛)
  9. , где 𝑔𝑐𝑑
  10.  — функция, считающая наибольший общий делитель. Затем сделаем тоже самое для столбцов матрицы и выведем ответ.
  11.  
  12. Как доказать, что это решение работает?
  13.  
  14. С одной стороны, если какой-то отрезок вида [1+𝑙𝑥,1+(𝑙+1)𝑥]
  15. , где 𝑙
  16.  — это значение из отрезка [0;𝑛𝑥−1]
  17. , содержит различные цифры, то тогда мы не сможем сжать заданную матрицу.
  18.  
  19. С другой стороны, если предыдущее условие верно, то мы можем сжать каждую строку по следующему алгоритму: откусим первые 𝑥
  20.  символов строки и сожмем оставшуюся строку рекурсивно. После такого сжатия мы получим матрицу размера 𝑛×𝑛𝑥
  21. . И из-за первого условия мы можем сжать оставшуюся матрицу снова при помощи этого алгоритма, если мы применим его к столбцам, а не строкам.
  22.  
  23. #include <bits/stdc++.h>
  24.  
  25. using namespace std;
  26.  
  27. const int N = 5200;
  28.  
  29. int n;
  30. bool a[N][N];
  31.  
  32. void parse_char(int x, int y, char c) {
  33.     int num = -1;
  34.     if (isdigit(c)) {
  35.         num = c - '0';
  36.     } else {
  37.         num = c - 'A' + 10;
  38.     }
  39.     for (int i = 0; i < 4; ++i) {
  40.         a[x][y + 3 - i] = num & 1;
  41.         num >>= 1;
  42.     }
  43. }
  44.  
  45. int main() {
  46. #ifdef _DEBUG
  47.     freopen("input.txt", "r", stdin);
  48. //  freopen("output.txt", "w", stdout);
  49. #endif
  50.    
  51.    
  52.     scanf("%d", &n);
  53.     char buf[N];
  54.     for (int i = 0; i < n; ++i) {
  55.         scanf("%s", buf);
  56.         for (int j = 0; j < n / 4; ++j) {
  57.             parse_char(i, j * 4, buf[j]);
  58.         }
  59.     }
  60.    
  61.     int g = n;
  62.    
  63.     for (int i = 0; i < n; ++i) {
  64.         for (int j = 0; j < n; ++j) {
  65.             int k = j;
  66.             while (k < n && a[i][k] == a[i][j]) ++k;
  67.             g = __gcd(g, k - j);
  68.             j = k - 1;
  69.         }
  70.     }
  71.    
  72.     for (int j = 0; j < n; ++j) {
  73.         for (int i = 0; i < n; ++i) {
  74.             int k = i;
  75.             while (k < n && a[k][j] == a[i][j]) ++k;
  76.             g = __gcd(g, k - i);
  77.             i = k - 1;
  78.         }
  79.     }
  80.    
  81.     cout << g << endl;
  82.    
  83.     return 0;
  84. }
Advertisement
Add Comment
Please, Sign In to add comment