题目
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 N.
For each Xbetween 1 and N inclusive,
she wants you to find out the maximum length of the substring which can be written as a concatenation of X same
strings. For clarification, a substring is a consecutive part of the original string.
Input
The first line contains T(T≤200),
the number of test cases. Most of the test cases are relatively small. T lines
follow, each contains a string of only small latin letters a
- z
,
whose length N is
less than 1000,
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 1, followed by Nintegers. The X-th (1-based) of them should be the maximum length of the substring which can be written as a concatenation of X same strings. If that substring doesn't exist, output 0 instead. See the sample for more format details.
Hint
For the second sample, the longest substring which can be written as a concatenation of 2 same
strings is noonnoon
, oonnoonn
, onnoonno
, nnoonnoo
,
any of those has length 8;
the longest substring which can be written as a concatenation of 3 same
strings is the string itself. As a result, the second integer in the answer is 8 and
the third integer in the answer is 12.
样例输入
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 ;
}