题意:这个题就是用一个最小的矩阵构成这个大的矩阵。
思路:把一个一维的最小覆盖子串变成一个二维的就可以了,一个字符串的最小覆盖子串是n - nex[n]。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define MAXN 10010
#define MAXE 100
#define INF 1000000000
#define MOD 10001
#define LL long long
#define ULL unsigned long long
#define pi 3.14159
using namespace std;
int nex[MAXN];
string str[MAXN];
int n, m;
void get_nex(const string &s) {
memset(nex, 0, sizeof(nex));
for (int i = 1, j = 0; i < s.length(); ++i) {
while (j && s[i] != s[j]) {
j = nex[j];
}
if (s[i] == s[j]) {
j++;
}
nex[i + 1] = j;
}
}
int gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, a % b);
}
}
int main() {
std::ios::sync_with_stdio(false);
while (cin >> n >> m) {
for (int i = 0; i < n; ++i) {
cin >> str[i];
}
int r, c;
int max_r = 0, max_c = 0;
for (int i = 0; i < n; ++i) {
get_nex(str[i]);
c = m - nex[m];
if (max_c == 0) {
max_c = c;
} else {
max_c = max_c * c / gcd(max(max_c, c), min(max_c, c));
}
if (max_c >= m) {
max_c = m;
break;
}
}
for (int i = 0; i < m; ++i) {
string temp = "\0";
for (int j = 0; j < n; ++j) {
temp += str[j][i];
}
get_nex(temp);
r = n - nex[n];
if (max_r == 0) {
max_r = r;
} else {
max_r = max_r * r / gcd(max(max_r, r), min(max_r, r));
}
if (max_r >= n) {
max_r = n;
break;
}
}
cout << max_r * max_c << endl;
}
return 0;
}