题意很简单,但是用到了之前没有了解过的kmp中next数组的性质(关于求最小循环节的)
关于这个性质怎么证明,我摊牌了,我不会,我只会用性质。
关于这个性质:
求出next数组后,设置变量 n = len - (next[len - 1] + 1)(这个+1是一个要注意的地方,因为next数组是最大前缀的最后一个字符坐标,而这里是要减的是最大前缀的长度,所以要加1)
如果len % n == 0说明n是这个字符串的最小循环节,所以只需要求出len / n即可
如果不能整除,就说明它的最小循环结是它自己,直接输出1即可
代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <string>
#include <cmath>
#include <cstdlib>
using namespace std;
const int MAXN = 1000005;
const int Size = 26;
char s[MAXN];
int nex[MAXN];
void getnext()
{
int j = -1,len = strlen(s);
nex[0] = -1;
for(int i = 1; i < len; i++){
while(j > -1&&s[j + 1] != s[i]){
j = nex[j];
}
if(s[j + 1] == s[i]){
j++;
}
nex[i] = j;
}
}
int main()
{
while(scanf("%s",s) == 1){
if(s[0] == '.') break;
int len = strlen(s);
memset(nex,0,sizeof(nex));
getnext();
/* for(int i = 0; i < len; i++)
cout<<nex[i]<<" ";
*/
int n = len - nex[len - 1] - 1;
if(len % n == 0) printf("%d\n",len / n);
else printf("1\n");
}
return 0;
}