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

原文地址:https://www.cnblogs.com/cutemush/p/12301822.html

时间: 2024-08-03 17:08:39

POJ 2185 Milking Grid--另一种字符串的循环节的相关文章

poj 2185 Milking Grid(KMP)

题目链接:poj 2185 Milking Grid 题目大意:给定一个N?M的矩阵,找到一个最小的r?c的矩阵,使得原矩阵可以由若干个小矩阵组成,输出r?c的值. 解题思路:将行和列分别看成字符串,然后hash,对hash后的数组分别求KMP. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef unsigned long long ll; con

POJ 2185 Milking Grid KMP循环节周期

题目来源:id=2185" target="_blank">POJ 2185 Milking Grid 题意:至少要多少大的子矩阵 能够覆盖全图 比如例子 能够用一个AB 组成一个 ABABAB ABABAB 能够多出来 思路:每一行求出周期 总共n个 求这n个周期的最小公倍数 假设大于m 取m 每一列求出周期 总共m个求这个m个周期的最小公倍数 假设大于n取n 答案就是2个最小公倍数的积 #include <cstdio> #include <cst

POJ 2185 Milking Grid (二维KMP next数组)

Milking Grid Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 6665   Accepted: 2824 Description Every morning when they are milked, the Farmer John's cows form a rectangular grid that is R (1 <= R <= 10,000) rows by C (1 <= C <= 75

POJ 2185 Milking Grid

Milking Grid Time Limit: 3000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: 218564-bit integer IO format: %lld      Java class name: Main Every morning when they are milked, the Farmer John's cows form a rectangular grid th

POJ 2185 Milking Grid(KMP)

解题思路: 算是一个多维的KMP,其实是一样的,不过把1个字符的比较改成一行或一列字符的比较,对行和列使用两次KMP,最后乘起来就可以了. #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <cmath> #include <vector> #include &l

POJ 2185 Milking Grid (搬运KMP)

题意:给你一个字母矩阵,让你找一个最小的字母矩阵,复制后可以得到大的矩阵,问最小矩阵面积是多少,假设原来的矩阵长度是6,你用一个长度为5的串复制,多余的部分不算,只算6以内相同即可 思路:其实没有什么思路,看了一些大佬们的博客,其中有几篇写的很棒 传送门1,传送门2 大体的思路就是找到每行的循环节,然后插入在桶中,在另一侧记录的时候发现等于列的数量是就代表这是最小的(细节部分窝还要想几天) 代码: 不存在的(最近搬运代码越来越熟练了) 原文地址:https://www.cnblogs.com/l

hdu1358 KMP求字符串最小循环节

对于一个字符串S,长度为L,如果由长度为len的字符串s(字符串s的最小循环节是其本身)循环k次构成,那么字符串s就是字符串S的最小循环节 那么字符串有个很重要的性质和KMP挂钩,即  i - next[i] 为字符串s的长度 i%(i - next[i]) ==0 证明:字符串S由s循环k次构成,那么有S[0-->L-len-1] == S[len-->L-1],即前k-1个循环节和后k-1个循环节构成的字符串相等 那么此时KMP数组的next[L] = k-1个循环节的长度, 也即 nex

KMP的妙用(利用next数组寻找字符串的循环节)

利用KMP的next数组的性质,我们可以找到next数组的循环节. 先说结论: 设字符串长n,则若其  i % ( i – next[n] ) == 0 ,则其有循环节(循环节数目大于1),其循环节数目为 i / ( i – next[n] ) 这里的next数组存储的是匹配到i匹配不成立时,下一个要匹配的位置.即next数组记录的是下一次匹配的位置,而不是下一次匹配的偏移量,若是记录的偏移量,只需修改一下公式即可. 言归正传,我们先证明第一个结论,根据下图来进行说明: 若结论中的关系成立(整除

【poj 1961】Period(字符串--KMP循环节)

题意:给你一个字符串,求这个字符串到第 i 个字符为止的重复子串的个数. 解法:判断重复子串的语句很重要!!if (p && i%(i-p)==0) printf("%d %d\n",i,i/(i-p)); 我之前一直不是很理解,而实际上多枚举几种情况就好了.若是重复的,那么next[i]肯定是最大值,值余下一个循环节不同:而若不是,next[i]表示的前缀和后缀串的和重叠部分不一样以外的部分就肯定空出来,不能整除的.(P.S.我在说些什么......m(._.)m)