POJ2185 Milking Grid【KMP】

来源:互联网 发布:淘宝面包鞋豆豆鞋 编辑:程序博客网 时间:2024/05/22 01:49

题目链接:

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;}


0 0
原创粉丝点击