给定 R×C 字符矩阵(R≤10000, C≤75),求最小面积子矩阵,使其平铺可覆盖原矩阵(子矩阵尺寸不必整除原尺寸)。
字符串 s[0..n-1] 的最小周期长度 = n - next[n],其中 next 为 KMP 失效函数(next[i] = 前缀函数值)。
#include <cstdio>
#include <cstring>
char s[10005][80], rs[80][10005];
int R[10005], C[10005];
int r, c;
void getNextR() { // 行方向
R[0] = -1;
int i = 0, j = -1;
while (i < r) {
if (j == -1 || strcmp(s[i], s[j]) == 0) {
++i; ++j; R[i] = j;
} else j = R[j];
}
}
void getNextC() { // 列方向(转置后)
C[0] = -1;
int i = 0, j = -1;
while (i < c) {
if (j == -1 || strcmp(rs[i], rs[j]) == 0) {
++i; ++j; C[i] = j;
} else j = C[j];
}
}
int main() {
while (scanf("%d%d", &r, &c) != EOF) {
for (int i = 0; i < r; ++i) scanf("%s", s[i]);
getNextR();
for (int i = 0; i < r; ++i)
for (int j = 0; j < c; ++j)
rs[j][i] = s[i][j];
getNextC();
printf("%d\n", (r - R[r]) * (c - C[c]));
}
return 0;
}
2 5 ABABA ABABA
二维模式匹配(如在大图中找小图)可用 2D KMP/Rabin-Karp,本题利用周期性简化为两次 1D KMP。