题目链接:点击打开链接
给你一个字符串矩阵,问你最小覆盖矩阵的面积是多少。
对每一行求最小覆盖子串的长度,对长度求最小公倍数,获得最小覆盖矩阵的长。同理,可以获得最小矩阵的宽。如果长或宽大于给
定矩阵的长或宽,那么所求最小覆盖矩阵的长或宽即为原矩阵的长或宽。
AC代码:
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
const int MAXN = 1e4 + 5;
int r, c, nxt[MAXN];
char s[MAXN][MAXN];
int getrow(int x)
{
nxt[0] = -1;
int i = 0, j = -1;
while(i < c) {
if(j == -1 || s[x][i] == s[x][j]) nxt[++i] = ++j;
else j = nxt[j];
}
return i - nxt[i];
}
int getcol(int x)
{
nxt[0] = -1;
int i = 0, j = -1;
while(i < r) {
if(j == -1 || s[i][x] == s[j][x]) nxt[++i] = ++j;
else j = nxt[j];
}
return i - nxt[i];
}
int gcd(int a, int b)
{
return b == 0 ? a : gcd(b, a % b);
}
int lcm(int a, int b)
{
return a / gcd(a, b) * b;
}
int main(int argc, char const *argv[])
{
while(scanf("%d%d", &r, &c) != EOF) {
memset(nxt, 0, sizeof(nxt));
for(int i = 0; i < r; ++i)
scanf("%s", s[i]);
int x = 1, y = 1;
for(int i = 0; i < r; ++i)
x = lcm(x, getrow(i));
for(int i = 0; i < c; ++i)
y = lcm(y, getcol(i));
if(x > c) x = c;
if(y > r) y = r;
printf("%d\n", x * y);
}
return 0;
}