POJ 2185 Milking Grid + kmp的巧妙应用

题意:

在字符矩阵中找出一个最小子矩阵,使其多次复制所得的矩阵包含原矩阵。

思路:

http://blog.sina.com.cn/s/blog_69c3f0410100tyjl.html

横向以及纵向的KMP预处理,横向的精美之初在于把每个串的每一个重复子串都累加记录在 f[] 数组中;

纵向的精美之处在于,把每个串都看成是一个字符进行比较。

代码如下:

#include <cstdio>
#include <cstdlib>
#include <cstring>

char s[10005][80];
int p[80];
int next[10005];
int f[80];

void getp(int k, int m)
{
    p[1] = 0;
    int j = 0;
    for (int i = 2; i <= m; ++i)
    {
        while (j > 0 && s[k][j+1] != s[k][i])
            j = p[j];
        if (s[k][j+1] == s[k][i])
            ++j;
        p[i] = j;

    }
}

int getp_r(int m)
{
    next[1] = 0;
    int j = 0;
    for (int i = 2; i <= m; ++i)
    {
        while (j > 0 && strcmp(s[j+1]+1, s[i]+1))
            j = next[j];
        if (!strcmp(s[j+1]+1, s[i]+1))
            ++j;
        next[i] = j;
    }
    return m - next[m];
}

int main()
{
    int r, c;
    scanf("%d %d", &r, &c);

    memset(f, 0, sizeof(f));
    for (int i = 1; i <= r; ++i)
    {
        scanf("%s", s[i] + 1);
        getp(i, c);
        int j = c;
        do {
            j = p[j];
            ++f[c-j];  
        } while (p[j]);
    }
    int i, x, y;
    for (i = 1; i < c; ++i)
        if (f[i] == r)
            break;
    x = i;
    y = getp_r(r);
    printf("%d\n", x * y);

    return 0;
}

 

-------------------------------------------------------

kedebug

Department of Computer Science and Engineering,

Shanghai Jiao Tong University

E-mail: kedebug0@gmail.com

GitHub: http://github.com/kedebug

-------------------------------------------------------

原文地址:https://www.cnblogs.com/kedebug/p/2755966.html