原题:
http://172.16.0.132/senior/#contest/show/1899/2
题目描述:
给定两个字符串a和b,我们可以定义一些操作:a*b为将字符串a和字符串b连接起来,比如a= “aoe”,b= “jkw”,那么a*b= “aoejkw”。进一步,我们可以有指数操作,a^0= “”, a^1=a, a^2=a*a, a^n=a*(a^(n-1))=a*a*…*a (n个a)
现在给你一个字符串,你可以将它看成是a^n的形式,比如字符串”abababab”,可以认为是”abab”^2, 也可以是”abababab”^1,还可以是”ab”^4。
现在问题是,给定的字符串,我们想让它变成a^n中的n达到最大,那么这个n最大是多少?例如:”abababab”最大的n是4。
输入:
第一行,一个整数m,表示有m个字符串。
接下来m行每行输入一个只含小写字母的字符串。
输出:
输出m行,对于每行输出相应字符串的最大n。
样例输入:
3
abcde
aaaaaa
abababab
样例输出:
1
6
4
数据范围限制:
30%的数据:字符串的长度≤1000;
100%的数据:字符串的长度≤1000000, m≤10,字符串内只含小写字母。
分析:
假设字符串为 S,长度为 N,子串 T 重复 K 次后得到串 S,那么 T 的长度一定为 L = N/K(要整除),则 T = S[1…L],将 S 拆分成 K 份,每份长度为 L,则有S[1…L] = S[L+1…2L] = S[2L+1…3L] = … = S[(K-1)L+1…KL];由于要保证 K 最大,势必 L 要取最小,所以根据 Next 函数的定义,有 Next[KL] = (K-1)L;即 Next[N] = N - L,所以 L = N - Next[N];
但是得出的长度 L 还要保证能被 N 整除,所以如果不能整除说明 L = N,即 K = 1;而如果能整除,那么 K = N / (N - Next[N]);
因而我们只要对字符串 S 做一趟 KMP,对其求 Next 数组;
实现:
#include<cstdio>
#include<string>
#include<iostream>
using namespace std;
string s;
int i,j,n,m,ans,p,a[10007];
bool c(int x)
{
int i,j;
i=1;
j=m/x;
while(s[i]==s[i+j]&&i+j<m) i++;
if(s[i]==s[i+j]) return true;
else return false;
}
int main()
{
scanf("%d",&n);
for(i=1;i<=n;i++)
{
cin>>s;
s='0'+s;
m=s.length()-1;
p=0;
ans=1;
for(j=2;j<=m;j++)
if(m%j==0)
{
p++;
a[p]=j;
}
for(j=p;j>=1;j--)
if(c(a[j]))
{
ans=a[j];
break;
}
printf("%d\n",ans);
}
}