利用kmp里的next数组的一道题

题目


E.T. Inc. employs Maryanna as alien signal researcher. To identify possible alien signals and background noise, she develops a method to evaluate the signals she has already received. The signal sent by E.T is more likely regularly alternative.

Received signals can be presented by a string of small latin letters a to z whose length is NN. For each XXbetween 11 and NN inclusive, she wants you to find out the maximum length of the substring which can be written as a concatenation of XX same strings. For clarification, a substring is a consecutive part of the original string.

Input

The first line contains T(T \le 200)T(T200), the number of test cases. Most of the test cases are relatively small. TT lines follow, each contains a string of only small latin letters a - z, whose length NN is less than 10001000, without any leading or trailing white spaces.

Output

For each test case, output a single line, which should begin with the case number counting from 11, followed by NNintegers. The XX-th (11-based) of them should be the maximum length of the substring which can be written as a concatenation of XX same strings. If that substring doesn't exist, output 00 instead. See the sample for more format details.

Hint

For the second sample, the longest substring which can be written as a concatenation of 22 same strings is noonnoonoonnoonnonnoonnonnoonnoo, any of those has length 88; the longest substring which can be written as a concatenation of 33 same strings is the string itself. As a result, the second integer in the answer is 88 and the third integer in the answer is 1212.

样例输入

2
arisetocrat
noonnoonnoon

样例输出

Case #1: 11 0 0 0 0 0 0 0 0 0 0
Case #2: 12 8 12 0 0 0 0 0 0 0 0 0


题目大意

  输入t个字符串,输出从1到strlen(str)的循环节的最大长度

 例如第二个样例,循环节为1个的可以把自己看成循环节最大长度就是12

  循环节为2个的情况是noonnoon , oonnoonn , onnoonno, nnoonnoo,长度是8

 循环节是3个的情况只有noonnoonnoon,这时候的单个循环节就是noon

 

解题思路

 利用next数组,next数组处理之后的跳变位置,我们利用next数组的特性,next[k] 与 next[next[k]]字符串相同的特性就可以找出最小的循环节,然后小的循环节如果能叠加变成一个大的循环节,例如ababababab,ab是一个小的循环节,abab则是叠加之后形成的一个大的循环节,同样利用next数组的特性处理即可,通过这题加深了对next数组的理解


代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std ;
const int maxn = 1000 + 10 ;
int nex[maxn] , c[maxn] ;
int case_ = 0 ;
void get_nex(char* s , int len)
{
    int  j = 0 ;
    nex[0] = 0 ;
    nex[1] = 0 ;
    for(int i = 2 ; i <= len ; i++)
    {
        while(j && s[j+1] != s[i])
            j = nex[j] ;
        if(s[j+1] == s[i])
            j++ ;
        nex[i] = j ;
    }
}
int main()
{
    int t ;
    char str[maxn] ;
    scanf("%d" , &t) ;
    while(t--)
    {
        memset(c , 0 , sizeof(c)) ;
        scanf("%s" , str+1) ;
        int len = strlen(str + 1) ;
        for(int i = 0 ; i < len ; i++)
        {
            int m = len - i ;
            get_nex(str + i , m) ;
            for(int j = 1 ; j <= m ; j++)
            {
                int tmp = j ;
                while(tmp) ///这里处理 上文提及的叠加处理
                {
                    tmp = nex[tmp] ;
                    if( j % (j - tmp) == 0)
                    {
                        int tt = j / (j - tmp) ;
                        c[tt] = max(c[tt] , j) ;
                    }
                }
            }
        }
        printf("Case #%d:", ++case_);
        for (int i = 1 ; i <= len ; i++)
            printf(" %d", c[i]);
        printf("\n");
    }
    return 0 ;
}



发布了69 篇原创文章 · 获赞 58 · 访问量 5万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章