B - Power Strings(KMP)
题目大意
输入一行字符串,该字符串是由一个最小字符串重复N次组成的(N>=1),要求输出N,
包含多行数据,输入为"."时结束,
数据量非常大,题目提示用scanf而非cin输入,题目没有给出字符串长度范围。
做法
字符串P长度m减去P的次长的相同前缀后缀即是最小字符串单元的长度,
用KMP算法求输入字符串P的次长的相同前缀后缀长度ma,
最小字符串单元长度mb=m-ma,输出ans=m / mb,
如果P的次长的相同前缀后缀长度为0,ans=1成立,
题目虽然没有给字符串长度范围,但实测MAXN=10^6够用。
AC-Code (C++)
Time: 125 ms Memory: 5.6 MB
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
const int MAXN = 1000005;
int nextt[MAXN];
char p[MAXN];
int m, ma, mb;
void nextt_function(void)
{
m = strlen(p);
int j = 0, k = -1; //nextt[j]=k表示字符串前j个字符的次长的相同前缀后缀长度为k
nextt[0] = -1;
while (j < m)
{
if (k == -1 || p[j] == p[k])
nextt[++j] = ++k;
else
k = nextt[k];
}
}
int main(void)
{
while (scanf("%s", p))
{
if (strcmp(p, ".") == 0)
break;
nextt_function();
ma = nextt[m];
mb = m - ma;
int ans = 1;
if (m % mb == 0) //还没看懂这步的意义,如果不判断会WA
ans = m / mb;
printf("%d\n", ans);
}
return 0;
}