给定一个字符串,求它最多由几个循环节构成。
思路:很自然地想到要求这个字符串最少后移几位后与自己匹配
#include <cstdio>
#include <cstring>
#define MX 10000001
using namespace std;
char src[MX],tar[MX];
int nxt[MX];
void getnext(int len)
{
int j=0;
nxt[0]=0;
for(int i=1;i<len;i++)
{
while(j>0&&src[j]!=src[i])j=nxt[j-1];
if(src[i]==src[j])j++;
nxt[i]=j;
}
}
int kmp(int lent,int lens)
{
int i=0,j=0;
while(i<lent&&j<lens)
{
if(tar[i]==src[j])i++,j++;
else
{
if(j==0)i++;
else j=nxt[j-1];
}
if(j==lens)return i-j;
}
return -1;
}
int main()
{
int tlen,slen;
while(scanf("%s",src))
{
if(src[0]=='.'&&strlen(src)==1)break;
memset(tar,0,sizeof(tar));
strcat(tar,src+1),strcat(tar,src);
slen=strlen(src),tlen=strlen(tar);
getnext(slen);
printf("%d\n",slen/(kmp(tlen,slen)+1));
}
return 0;
}
3 条评论
litble · 2017年4月24日 8:55 下午
我是在批判这个算法….. 不仅仅是代码长度的问题,这个算法的复杂度也不够优化啊。
boshi · 2018年3月8日 10:17 下午
明明都是 O(n),而且我能求出所有的循环节。
konnyakuxzy · 2018年3月8日 10:36 下午
Orz 您太强了
我现在才做这道题
而且还恬不知耻地发了题解 QvQ
我太弱了