Description
回文序列是指左右对称的序列。例如1 2 3 2 1是回文序列,但是1 2 3 2 2就不是。我们会给定一个N×M的矩阵,你需要从这个矩阵中找出一个P×P的子矩阵,使得这个子矩阵的每一列和每一行都是回文序列。
Solution
果然竞赛要有信仰→
任意一个回文的矩形都是可以由小一圈的回文矩形+最外圈上都是回文串,那么这样子 O(n3) 暴力一下判断就行了。如果还想快一点可以预处理回文的情况,但这样就要考虑MLE了
Code
#include <stdio.h>
#define rep(i, st, ed) for (int i = st; i <= ed; i += 1)
#define min(x, y) (x)<(y)?(x):(y)
#define N 301
int rc[N][N];
bool isPr[N][N][N];
int main(void){
int n, m;
scanf("%d%d", &n, &m);
rep(i, 1, n){
rep(j, 1, m){
scanf("%d", &rc[i][j]);
isPr[i][j][1] = 1;
}
}
rep(i, 1, n - 1){
rep(j, 1, m - 1){
if (rc[i][j] == rc[i + 1][j] && rc[i][j] == rc[i][j + 1] && rc[i][j] == rc[i + 1][j + 1]){
isPr[i][j][2] = 1;
}
}
}
int ans = 0;
int mn = min(n, m);
rep(k, 1, mn){
rep(i, 2, n - k){
rep(j, 2, m - k){
if (isPr[i][j][k]){
bool flag = false;
for (int l = j - 1, r = j + k; l <= r; l += 1, r -= 1){
if (rc[i - 1][l] ^ rc[i - 1][r] || rc[i + k][l] ^ rc[i + k][r] || rc[i - 1][l] ^ rc[i + k][l] || rc[i - 1][r] ^ rc[i + k][r]){
flag = true;
break;
}
}
if (flag){
continue;
}
for (int l = i - 1, r = i + k; l <= r; l += 1, r -= 1){
if (rc[l][j - 1] ^ rc[r][j - 1] || rc[l][j + k] ^ rc[r][j + k] || rc[l][j - 1] ^ rc[l][j + k] || rc[r][j - 1] ^ rc[r][j + k]){
flag = true;
break;
}
}
if (!flag){
isPr[i - 1][j - 1][k + 2] = 1;
if (k + 2 > ans){
ans = k + 2;
}
}
}
}
}
}
printf("%d\n", ans);
return 0;
}