題目
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 ;
}