题意:循环节
思路:kmp
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; #define MaxSize 100005 int _next[MaxSize]; void GetNext(char t[]){//求next数组 int j,k,len; j=0; k=-1; _next[0]=-1; len=strlen(t); while(j<len){ if(k==-1||t[j]==t[k]){ ++j; ++k; _next[j]=k;//此句可由优化替代 /*优化(仅保证求KMPIndex时可用。谨慎使用。) if(t[j]!=t[k])next[j]=k; else next[j]=next[k]; */ } else k=_next[k]; } } int main(){ char str[MaxSize]; int t,i,len,len2; scanf("%d",&t); while(t--){ scanf("%s",str); len=strlen(str); GetNext(str);//求子串的next数组 if(_next[len]==0)printf("%d\n",len); else{ len2=len-_next[len];//最小循环节 if(len%len2==0)printf("0\n"); else printf("%d\n",len2-len%len2); } } return 0; }
关于循环节,参考原文:kmp next函数 kmp的周期问题,深入了解kmp中next的原理
-----------------------
-----------------------
k m x j i
由上,next【i】=j,两段红色的字符串相等(两个字符串完全相等),s[k....j]==s[m....i]
设s[x...j]=s[j....i](xj=ji)
则可得,以下简写字符串表达方式
kj=kx+xj;
mi=mj+ji;
因为xj=ji,所以kx=mj,如下图所示
-------------
-------------
k m x j
看到了没,此时又重复上面的模型了,kx=mj,所以可以一直这样递推下去
所以可以推出一个重要的性质len-next[i]为此字符串的最小循环节(i为字符串的结尾),另外如果len%(len-next[i])==0,此字符串的最小周期就为len/(len-next[i]);
时间: 2024-10-23 00:32:35