您的位置:首页 > 其它

POJ Problem 2406 Power Strings

2016-11-08 21:32 393 查看
定义两个字符串a*b是它们的串联,字符串的非负指数为:a^0 = "",a^(n+1) = a*a^n。

现给定一个字符串s,求最大的指数n使得s=a^n。

定理:假设s的长度为len,则s存在循环子串,当且仅当len可以被len-next[len]整除,最短循环子串为s[len-next[len]]

例子证明:
设s=q1q2q3q4q5q6q7q8,next[8]
= 6,此时str = s[len-next[len]] = q1q2,由字符串特征向量next的定义可知,q1q2q3q4q5q6 =
q3q4q5q6q7q8,即有q1q2=q3q4,q3q4=q5q6,q5q6=q7q8,即q1q2为循环子串,且易知为最短循环子串。由以上过程可知,若len可以被len-next[len]整除,则s存在循环子串否则不存在。

#include <string.h>
#include <vector>
#include <stdio.h>
using namespace std;

void nextArr(char s[], vector<int>& next){
int n = next.size();
next[0] = 0;
for(int i = 1; i < n; ++i){
int j = next[i-1];
while(j > 0 && s[i] != s[j])
j = next[j-1];
if(j >= 0 && s[i] == s[j])
next[i] = j+1;
else
next[i] = 0;
}
}

int main(){
char str[1000001];
while(scanf("%s", str) != EOF){
if(str[0] == '.')
break;
int len = strlen(str);
if(len == 0){
printf("0\n");
continue;
}
vector<int> next(len, 0);
nextArr(str, next);
if(len%(len-next[len-1]) == 0)
printf("%d\n", len/(len-next[len-1]));
else
printf("1\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM题解 poj KMP