http://poj.org/problem?id=2406
题目意思很明确,确定一个a使得a^n=s,使得s最大,这个题目初看时,貌似需要找到最小的a,然后才能求出s,但这样肯定会超时。想到用KMP算法,将S当作模式串,对S进行一次自我匹配后,就可以找到了最小的a的长度了,其中先计算lena = lens - next[lens] ,然后判断lena是否能被lens 整除,如果能整除,则说明lena就是最小的长度,并且lens/lena 就是所要求的n,否则说明整个字符串的最小长度即为lens。理由如下,如果字符串s能表示成a^n,其中n大于1,则必定可以导出next[lens] = lens - lena , 理由很简单,由于KMP每次匹配的时候总是得到当前匹配长度最长的串(位移最短,对于有多个相同的串a组成的串s而言,最短位移即为一个a的长度)。而如果不存在的时候,考虑串s的一般组成形式为ata,则next[lens] = lena ,此时一定无法使得(lens- lena)整除lens。故而可以判断出来。程序如下:
/*
ID: csuchenan
PROG:POJ 2406 Power strings
LANG: C++
*/
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std ;
const int maxn = 100000005 ;
char patt[maxn] ;
int next[maxn] ;
int len ;
int main()
{
while(scanf("%s" , patt + 1)!=EOF)
{
if(patt[1] == '.')
break ;
len = strlen(patt+1) ;
memset(next , 0 , len + 1) ;
int i ;
int k ;
next[1] = 0 ;
k = 0 ;
for(i = 2 ; i <= len ; i ++)
{
while(k > 0 && patt[k+1] != patt[i])
k = next[k] ;
if(patt[k+1] == patt[i])
k ++ ;
next[i] = k ;
}
k = len - next[len] ;
if(len%k==0)
printf("%d\n" , len/k) ;
else
printf("%d\n" , 1) ;
}
return 0 ;
}