您的位置:首页 > 其它

HDU 3374 String Problem (KMP+最大最小表示)

2014-08-07 10:46 375 查看
KMP,在有循环节的前提下:循环节t=len-next[len],个数num=len/(len-next[len]);
个人理解,如果有循环节,循环节长度必定小于等于len/2,换句话说next[len]>=len/2;
对于len%(len-next)!=0的这种情况不讨论,循环节不存在。
下面是假设循环节存在的情况
当次数等于2,对于abcabc这种情况就不用说了,len=6,next[len]=3;
当次数大于2,
对于串a1a2a3a4a5a6a7a8a9
如果有
a1a2a3a4a5a6
a4a5a6a7a8a9
next[len]=6,len=9;
说明a7a8a9=a4a5a6;
a1a2a3=a4a5a6;
循环节就很明显了,其它情况也是类似与这样讨论。
所以。。。。。
viewcode#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
usingnamespacestd;
constintN=1e6+10;
chars
;
intnext
;

voidgetnext(char*s,int*next,intlen)
{
intj=0,i=1;
next[1]=0;
while(i<len)
{
if(j==0||s[i]==s[j])next[++i]=++j;
elsej=next[j];
}
}

intgetsub(char*s,boolflag,intlen)
{
inti=0,j=1,k=0;
while(i<len&&j<len&&k<len)
{
if(i==j)j++;
intni=i+k,nj=j+k;
if(ni>=len)ni-=len;
if(nj>=len)nj-=len;
if(s[ni]>s[nj])
{
if(flag)i+=k+1;
elsej+=k+1;
k=0;
}
elseif(s[ni]<s[nj])
{
if(flag)j+=k+1;
elsei+=k+1;
k=0;
}
elsek++;
}
returni;
}

intmain()
{
while(scanf("%s",s)>0)
{
intlen=strlen(s);
getnext(s,next,len);
intt=len-next[len];
t=(len%t?1:len/t);
intminsub=getsub(s,true,len)+1;
intmaxsub=getsub(s,false,len)+1;
printf("%d%d%d%d\n",minsub,t,maxsub,t);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: