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 }