题意:
给定两个字符串a和b,定义式子:a*b表示两个字符串的连接,例如:a = “abc”, b = “def” 则:a*b = “abcdef”。如果将连乘看成乘法,则按照普遍的方法一个非负整数的幂表示如下: a^0 = “” (the empty string) and a^(n+1) = a*(a^n).
输入:
输入字符串S每组样例一行,S为可打印字符.S长度在1~1000000之间,最后一组数据后为“.”表示结束。
输出:
每个S输出最大的n满足:S = a^n,其中a为任意字符串。
分析:
题目大意:给出一个字符串,求出他的最小重复单元是什么,进而再求出重复次数,例如:“aaaa”最小重复单元是“a”重复次数是4;
解题思路:设字符串S = “abcabc”求其next数组:
S: a b c a b c
next[j]: -1 0 0 0 1 2 3
在这里为了计算要多算出一位,那么可能成为最小重复单元的长度可由下面的规则确定:
(1)若2*next[len] < len 则最小重复单元长度为len那么他重复次数为1
(2)若2*next[len] > len 则:
1>:如果len%(len-next[len]) == 0则最小重复单元长度为len – next[len],那么其重复次数为len/(len-next[len]).
2>:如果len%(len – next[len]) != 0 则最小重复单元长度为:len,那么其重复次数为1
好好揣摩以上两点!
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXN = 1000010;
int next[MAXN];
void Get_next(char* str)
{
int i = 0, j = -1;
next[0] = -1;
int len = strlen(str);
while(i < len)
{
if(j == -1 || str[i] == str[j])
{
++i;
++j;
next[i] = j;
}
else
j = next[j];
}
}
int main()
{
char str[MAXN];
while(~scanf("%s", str))
{
if(str[0] == '.')
break;
Get_next(str);
int len = strlen(str);
if(2*next[len] < len)
cout<<"1"<<endl;
else
{
if(len % (len - next[len]) == 0)
cout<<len/(len-next[len])<<endl;
else
cout<<"1"<<endl;
}
}
return 0;
}