HDU 3746 Cyclic Nacklace 环形项链(KMP,循环节)

时间:2024-04-26 08:04:57

题意:

  给一个字符串,问:要补多少个字符才能让其出现循环?出现循环是指循环节与字符串长度不相等。比如abc要补多个变成abcabc。若已经循环,输出0。

思路:

  根据最小循环节的公式,当len%(len-next[len])==0时,最小循环节为len/(len-next[len]),而当len%(len-next[len])!=0时,就没有循环节。可以通过在串尾补上一些字符,使得len%(len-next[len])==0,就会出现循环节了。

 #include <bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
#define INF 0x7f7f7f7f
using namespace std;
const int N=;
char str[N];
int _next[N]; void get_next(int len)
{
_next[]=-;
int i=, j=-; //模式串
while(i<len)
{
if(j==-||str[j]==str[i]) _next[++i]=++j;
else j=_next[j];
}
} int main()
{
freopen("input.txt", "r", stdin);
int t, len=;
cin>>t;
while(t--)
{
scanf("%s",str);
get_next(len=strlen(str));
if(_next[len]==) printf("%d\n",len); //这是没有循环节的情况
else if(len%(len-_next[len])==) puts(""); //有循环了
else //整串不循环,补字符凑循环
{
int i=;
while( i<len && (len+i)%(len-_next[len])!=) i++;//尝试在后面添加匹配的字符,最长不超len
printf("%d\n", i);
}
}
return ;
}

AC代码