KMP算法用来解决一系列字符串单模式匹配问题,其以难理解,难记忆著称。其next数组的构造就如同AC自动机中的fail指针,就是如果匹配失败,字符串应从哪里开始继续匹配。这里的next数组表示:next[i]=前i个字符的公共最长前后缀长度。觉得对于KMP算法,这篇写的不错——http://www.cnblogs.com/c-cloud/p/3224788.html。
给定两个字符串a和b,我们可以定义一些操作:a*b为将字符串a和字符串b连接起来,比如a= "aoe",b= "jkw",那么a*b= "aoejkw"。进一步,我们可以有指数操作,a^0= "", a^1=a, a^2=a*a, a^n=a*(a^(n-1))=a*a*…*a (n个a)
现在给你一个字符串,你可以将它看成是a^n的形式,比如字符串"abababab",可以认为是"abab"^2, 也可以是"abababab"^1,还可以是"ab"^4。
现在问题是,给定的字符串,我们想让它变成a^n中的n达到最大,那么这个n最大是多少?例如:"abababab"最大的n是4。
这道题一看觉得不是特别会,暴力算法老王的bloghttp://www.cnblogs.com/TUncleWangT/p/7162665.html讲了,正解就是运用了KMP算法里的next数组。我们令原字符串长度为S,重复字符串长度为T,则S=K*T,由定义可知next[S]=(K-1)*T;所以S-next[S]=T,判断一下整除就好了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
char str[1000005];
int next[1000005];
void make_next()
{
int len=strlen(str),q,k;
next[0]=0;
for(q=1,k=0;q<len;q++)
{
while(k>0&&str[q]!=str[k])
{
k=next[k-1];
}
if(str[k]==str[q])
k++;
next[q]=k;
}
}
void Debug()
{
int len=strlen(str);
for(int i=0;i<len;i++)
cout<<next[i]<<‘ ‘;
}
void work()
{
int tmp=strlen(str)-next[strlen(str)-1];
if(strlen(str)%tmp==0) cout<<(strlen(str)/tmp)<<endl;else cout<<1<<endl;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s",str);
make_next();
work();
}
}