Period HDU 1358 KMP next数组性质的应用
Posted alking1001
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Period HDU 1358 KMP next数组性质的应用相关的知识,希望对你有一定的参考价值。
Period HDU 1358 KMP next数组性质的应用
题意
题目的意思是给你一个字符串,判断这个字符串的前缀字符串中,哪些是周期串,输出这个前缀字符串的长度和这个前缀字符串中循环节的个数。
解题思路
这道题考察的是KMP
算法中next
数组的应用,必须理解透next[]
数组代表的含义才能通过它解决这道题。
思路是先构造出 next[]
数组,下标为i
,定义一个变量 j = i - next[i]
就是next
数组下标和下标对应值的差,如果这个差能整除下标 i
,即i%j==0
,则说明下标i
之前的字符串(周期性字符串长度为 i
)一定可以由一个前缀周期性的表示出来,这个前缀的长度为刚才求得的那个差,即j
,则这个前缀出现的次数为 i/j
。所以最后输出i和i/j
即可。
注意:这里求next的算法不能是那种简化形式的。
这里需要特殊处理的是next[i] = 0
或者next = -1
要忽略。
代码实现
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<stack>
#include<queue>
#include<map>
using namespace std;
const int MAXN=1e6+7;
char s[MAXN];
int nx[MAXN], n;
void get_next()
{
int j=0, k=-1, len=n;
nx[0]=-1;
while(j<len)
{
if(k == -1 || s[j] == s[k])
{
j++; k++;
nx[j] = k;
}
else k = nx[k];
}
}
int main()
{
int count=1;
while( scanf("%d", &n) && n!=0)
{
int j=0;
scanf("%s", s);
get_next();
printf("Test case #%d
", count++);
for(int i=2; i<=n; i++)
{
if(nx[i] <= 0)
continue;
j = i - nx[i];
if(i % j == 0)
printf("%d %d
", i, i/j);
}
printf("
");
}
return 0;
}
以上是关于Period HDU 1358 KMP next数组性质的应用的主要内容,如果未能解决你的问题,请参考以下文章