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 }
来源:https://www.cnblogs.com/npugen/p/10802967.html