HDU 3746 (KMP求最小循环节) Cyclic Nacklace

题意:

给出一个字符串,要求在后面添加最少的字符是的新串是循环的,且至少有两个循环节。输出最少需要添加字符的个数。

分析:

假设所给字符串为p[0...l-1],其长度为l

有这样一个结论:

这个串的最小循环节为 l - next[l]

感觉自己想得不是特别透彻,所以把别人的博客贴上来吧。

里面有个小错误就是:next[i]的值应该为j-k

对于这种情况还可以这样想:

|←②→|←④→|

------------------------

------------------------

|←①→|←③→|

这是同一个字符串

其中红色代表相同的前缀和后缀

前面那段黄的(①段)等于上面对应等长的红的部分(②段),因为前缀和后缀相同,所以②段和③段相同,③段又和正上方的④段相同,以此类推。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = 100000 + 10;
char p[maxn];
int next[maxn]; void get_next(char* p, int l)
{
int k = -1, j = 0;
next[0] = -1;
while(j < l)
{
if(k == -1 || p[k] == p[j])
{
k++;
j++;
next[j] = k;
}
else k = next[k];
}
} int main(void)
{
//freopen("3746in.txt", "r", stdin);
int T;
scanf("%d", &T);
while(T--)
{
memset(next, 0, sizeof(next));
scanf("%s", p);
int l = strlen(p);
get_next(p, l);
if(next[l] == 0)
{
printf("%d\n", l);
continue;
}
int cir = l - next[l];
if(l % cir == 0)
{
puts("0");
continue;
}
printf("%d\n", cir - (l % cir));
} return 0;
}
上一篇:python datetime模块


下一篇:基于MVC4+EasyUI的Web开发框架形成之旅--附件上传组件uploadify的使用