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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值