POJ 2185 Milking Grid--另一种字符串的循环节

在Power String中,求一个字符串的循环节,应满足L mod (L-next[L])=0,则循环节长度为L-next[L]

存在另一种形式的循环节,例如abcabca,此时如果将abc重写三次,得到abcabcabc,则原字符串为其前缀.

此时对于原字符串,其循环节长度为L-next[L]=7-4=3,循环节为abc.具体可见下面这个题

[Baltic2009]Radio Transmission

给你一个字符串,它是由某个字符串不断自我连接形成的。 但是这个字符串是不确定的,现在只想知道它的最短长度是多少.
Input

第一行给出字符串的长度,1 < L ≤ 1,000,000. 第二行给出一个字符串,全由小写字母组成.
Output

输出最短的长度
Sample Input

8

cabcabca
Sample Output

3
HINT

对于样例,我们可以利用"abc"不断自我连接得到"abcabcabc",读入的cabcabca,是它的子串

#include <cstdio>
 
#define MAXN 1000002
 
using namespace std;
 
char s[MAXN];
int next[MAXN];
int n;
 
void solve()
{
    next[1] = 0;
    int j = 0;
    for (int i = 2; i <= n; i ++)
    {
        while ((j) && (s[j + 1] != s[i])) j = next[j];
        if (s[j + 1] == s[i]) j ++;
        next[i] = j;
    }
    printf("%d\n", n - next[n]);
}
 
int main()
{
    scanf("%d\n%s", &n, s + 1);
    solve();
    return 0;
}

  

对于Milking Gird

Sol:

将大矩阵的每一列看成一个字符,然后对该大矩阵的每一列求出next[i],则列最短循环节长度=小矩阵的宽=ans1=c-next[c]。        

将大矩阵的每一行看成一个字符,然后对该大矩阵的每一行求出next[j],则行最短循环节长度=小矩阵的高=ans2=r-next[r]。        

最后答案:ans1*ans2即为所求矩阵的面积。

#include<bits/stdc++.h>
using namespace std;
char s[10010][100];
int next[10010];
int r,c;
bool str1(int i,int j)//判断第i行和第j行是否相等
{
    for(int k=0;k<c;k++)
        if(s[i][k]!=s[j][k])
            return false;
    return true;
}
bool str2(int i,int j)//判断第i列和第j列是否相等
{
    for(int k=0;k<r;k++)
        if(s[k][i]!=s[k][j])
            return false;
    return true;
}
int main()
{
    while(scanf("%d%d",&r,&c)==2)
    {
        for(int i=0;i<r;i++)
            scanf("%s",s[i]);
        next[0]=next[1]=0;
        for(int i=1;i<r;i++)//把每行看成一个字符
        {
            int j=next[i];
            while(j && str1(i,j)==false) j=next[j];
            next[i+1] = (str1(i,j)==true)? j+1 :0;
        }
     
        int ans1=r-next[r];
        next[0]=next[1]=0;
        for(int i=1;i<c;i++)//把每列看成一个字符
        {
            int j=next[i];
            while(j && str2(i,j)==false) j=next[j];
            next[i+1] = (str2(i,j)==true)? j+1 :0;
        }
        int ans2=c-next[c];
     
        printf("%d\n",ans1*ans2);
    }
}
//原文链接:https://blog.csdn.net/u013480600/article/details/22990715

猜你喜欢

转载自www.cnblogs.com/cutemush/p/12301822.html