Educational Codeforces Round 59 (Rated for Div. 2) - D. Compression(思维)

Problem  Educational Codeforces Round 59 (Rated for Div. 2) - D. Compression

Time Limit: 2500 mSec

Problem Description

Input

 

Output

 Print one number: maximum x such that an x-compression of the given matrix is possible.

Sample Input

8
E7
E7
E7
00
00
E7
E7
E7

Sample Output

1

 

题解:首先可以知道对于一个符合条件的x,原矩阵要能够划分成 x * x的小矩阵,每个小矩阵中的元素是相同的,这是充要条件。接下来就是从大到小遍历n的约数判断是否满足该条件即可,如果每次都暴力判断那最差的情况下是O(约数个数 * n^2),约数的数量多一点就无法承受,主要到矩阵中的元素只可能是0和1,那么如果小矩阵中元素都相等,那么就都为0或者都为1,这时就可以通过小矩阵的元素和来判断是否元素都相同。想到这题目就结束了,二维前缀和预处理一下即可。

 

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 #define REP(i, n) for (int i = 1; i <= (n); i++)
  6 #define sqr(x) ((x) * (x))
  7 
  8 const int maxn = 5200 + 5;
  9 const int maxt = 600 + 10;
 10 const int maxm = 200000 + 100;
 11 const int maxs = 52;
 12 
 13 typedef long long LL;
 14 typedef pair<int, int> pii;
 15 typedef pair<double, double> pdd;
 16 
 17 const LL unit = 1LL;
 18 const int INF = 0x3f3f3f3f;
 19 const LL Inf = 0x3f3f3f3f3f3f3f3f;
 20 const double eps = 1e-14;
 21 const double inf = 1e15;
 22 const double pi = acos(-1.0);
 23 const LL mod = 1000000007;
 24 
 25 int n;
 26 bool gra[maxn][maxn];
 27 int dp[maxn][maxn];
 28 char str[maxn];
 29 
 30 inline int cal(char ch)
 31 {
 32     if (isdigit(ch))
 33         return ch - '0';
 34     return ch - 'A' + 10;
 35 }
 36 
 37 void Fill(int x, int y, char ch)
 38 {
 39     int num = cal(ch);
 40     for (int j = 3; j >= 0; j--)
 41     {
 42         if (num & (1 << j))
 43             gra[x][y + 3 - j] = true;
 44     }
 45 }
 46 
 47 void DP()
 48 {
 49     for (int i = 1; i <= n; i++)
 50     {
 51         for (int j = 1; j <= n; j++)
 52         {
 53             dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + gra[i][j];
 54         }
 55     }
 56 }
 57 
 58 bool solve(int l)
 59 {
 60     int tot = l * l;
 61     for (int i = l; i <= n; i += l)
 62     {
 63         for (int j = l; j <= n; j += l)
 64         {
 65             int sum = dp[i][j] - dp[i - l][j] - dp[i][j - l] + dp[i - l][j - l];
 66             if (sum && sum != tot)
 67             {
 68                 return false;
 69             }
 70         }
 71     }
 72     return true;
 73 }
 74 
 75 void out()
 76 {
 77     for (int i = 1; i <= n; i++)
 78     {
 79         for (int j = 1; j <= n; j++)
 80         {
 81             cout << dp[i][j] << " ";
 82         }
 83         cout << endl;
 84     }
 85 }
 86 
 87 int main()
 88 {
 89     //ios::sync_with_stdio(false);
 90     //cin.tie(0);
 91     //freopen("input.txt", "r", stdin);
 92     //freopen("output.txt", "w", stdout);
 93     memset(gra, 0, sizeof(gra));
 94     scanf("%d", &n);
 95     for (int i = 1; i <= n; i++)
 96     {
 97         scanf("%s", str);
 98         for (int j = 0; j < n / 4; j++)
 99         {
100             Fill(i, j * 4 + 1, str[j]);
101         }
102     }
103     DP();
104     //out();
105     int ans = 0;
106     for (int x = n; x >= 2; x--)
107     {
108         if (n % x)
109             continue;
110         if (solve(x))
111         {
112             ans = x;
113             break;
114         }
115     }
116     if (!ans)
117     {
118         cout << 1 << endl;
119     }
120     else
121     {
122         cout << ans << endl;
123     }
124 
125     return 0;
126 }

 

posted on 2019-05-02 18:23  随缘&不屈  阅读(196)  评论(0编辑  收藏  举报

导航