思路:
时间长没写kmp了,导致这题一直看错题,想错地方,wa了好多次仔细看了题面描述才反应过来。
这题只是简单的让求循环节长度,保证了每个字符串加上几个字符或者不加一定可以构成由一个字符串循环的。
那么只需要求循环节长度,然后看看多出了几个,就隔过去输出相应长度的循环节即可。
Code:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
const int AX = 2e5+666;
char ps[AX];
int len ;
int next1[AX];
void getnext1( int m ){
next1[0] = -1;
int j = 0;
int k = -1;
while ( j < m ) {
if (k == -1 || ps[j] == ps[k]){
next1[++j] = ++k;
}else{
k = next1[k];
}
}
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&len);
scanf("%s",ps);
getnext1(len);
/* for( int i = 0 ; i <= len ; i++ ){
cout << next1[i] << ' ';
}cout << endl;*/
int ans = len - next1[len];
int left = next1[len] % ans ;
printf("%d\n",ans);
for( int i = len - left - ans ; i < len - left ; i ++ ){
printf("%c",ps[i]);
}printf("\n");
}
return 0;
}
另外复习:
如果 i % ( i - next[i] ) == 0 && next[i] != 0 ) , 那么说明i之前的字符串可以构成由一个循环节循环得到。
循环节长度为: i - next[i]
循环次数为: i / ( i - next[i] )
这题用不上。