标签:
题目链接:
http://poj.org/problem?id=2185
题目大意:
有一个N行M列的字符矩阵,这个字符矩阵可以由较小的矩阵重复平铺组成整个矩阵。问:
最小的字符子矩阵的面积为多少。
思路:
对于长度为M的每一行s[i]来说,M-Next[M],M-Next[Next[M]],…都是能通过复制,完
全覆盖字符串的可行串,而M-Next[M]是最小的。遍历每一行,求出对所有s[i]都可行的最
小字符串长度,即每一行M-Next[M]的最小公倍数lcmn。再用类似的方法求出长度为N、
对每一列都可行的最小字符串高度,即每一列N-Next[N]的最小公倍数lcmm。则最后结果
就是lcmn*lcmm。
AC代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; const int MAXN = 10010; int Next[MAXN],Num[110],M,N; char s[MAXN][110]; int Gcd(int a,int b) { if(a < b) int temp = a,a = b,b = temp; if(b == 0) return a; return Gcd(b,a%b); } int Lcm(int a,int b) { return a/Gcd(a,b)*b; } void GetNext1(int h) { int i = 0,j = -1; int len = strlen(s[h]); Next[0] = -1; while(i <= len) { if(j == -1 || s[h][i]== s[h][j]) { i++,j++; Next[i] = j; } else j = Next[j]; } } void GetNext2(int w) { int i = 0,j = -1; int len = N; Next[0] = -1; while(i <= len) { if(j == -1 || s[i][w] == s[j][w]) { i++,j++; Next[i] = j; } else j = Next[j]; } } int main() { while(cin >> N >> M) { getchar(); int lcmn = 1; for(int i = 0; i < N; ++i) cin >> s[i]; for(int i = 0; i < N; ++i) { GetNext1(i); lcmn = Lcm(lcmn,M-Next[M]); if(lcmn >= M) { lcmn = M; break; } } int lcmm = 1; for(int i = 0; i < M; ++i) { GetNext2(i); lcmm = Lcm(lcmm,N-Next[N]); if(lcmm >= N) { lcmm = N; break; } } cout << lcmm*lcmn << endl; } return 0; }
标签:
原文地址:http://blog.csdn.net/lianai911/article/details/45174651