HDU-1358 Period KMP
题义是求给定的一个串在任意字符时,那么这么一个前缀能否被表示为该前缀的子串通过至少两次循环得到。样例中的 "aaa" 表示在第二号位置可以通过循环两次得到,循环节当然是 "a" 了,而在三号位置可以通过循环三次得到,循环节当然还是 "a" 了。
上一道题目(HDU 3736)我们已经找到了循环节的公式,所以这里直接在每一位直接判断是否为一个合法的循环结构即可。
代码如下:
#include <iostream>
#include <cstring>
using namespace std;
char str[1000005]; /**/ int next[1000005];
void getnext( char *s, int *next )
{
int k= 1, j= 0, len= strlen( str+ 1 );
while( k<= len )
{
if( j== 0|| s[j]== s[k] )
{
++j, ++k;
next[k]= j;
}
else
{
j= next[j];
}
}
}
int main( )
{
int N, cnt= 0;
while( cin>> N, N!= 0 )
{
cin>> str+ 1;
int len= strlen( str+ 1 );
getnext( str, next );
cout<< "Test case #"<< ++cnt<< endl;
for( int i= 2; i<= len; ++i )
{
int loop= i- next[i+ 1]+ 1;
if( i% loop== 0&& i/ loop> 1 ) //后面的判断不能少
{ // 必须有一个以上的循环
cout<< i<< " "<< i/ loop<< endl;
}
}
cout<< "\n";
}
return 0;
}


浙公网安备 33010602011771号