题目链接:FZU1901
题意:给出一个字符串,问可以看作由长度多少的子串循环得到,最后一周期可以不全。题目分析:这题可以KMP,next数组求公共的子串,取next[len],之前求循环节的知道,len-next[len]就是最短的循环节,依次递归地求next用子串长度减就是子串的最短循环节,加上原来的子串外的那部分就是新的循环节(子串外部分也是子串的循环节)这个在纸上画一画基本都出来了。两者加在一起就是len-nexts[buf],其中buf为依次递归求nexts的值。
//
// main.cpp
// FZU1901
//
// Created by teddywang on 16/5/19.
// Copyright © 2016年 teddywang. All rights reserved.
//
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char s[2000100];
int nexts[2000100],sum[2000100];
int len,n,num;
void getnexts(char *s)
{
int i=0,j=-1;
nexts[0]=-1;
while(i<len)
{
if(s[i]==s[j]||j==-1)
{
nexts[++i]=++j;
}
else j=nexts[j];
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%s",s);
len=strlen(s);
getnexts(s);
num=0;
//int buf=len-nexts[len];
int buf=len;
while(buf)
{
buf=nexts[buf];
sum[num++]=len-buf;
}
//if(buf>0)
//{
// for(int j=1;j*buf<len;j++)
// sum[num++]=j*buf;
//}
//sum[num++]=len;
printf("Case #%d: %d\n",i,num);
for(int j=0;j<num-1;j++)
printf("%d ",sum[j]);
printf("%d\n",sum[num-1]);
}
}