hdu 1358:Period(KMP算法,next[]数组的使用)
2014-03-07 15:24
323 查看
Period
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2398 Accepted Submission(s): 1187
[align=left]Problem Description[/align]
For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the prefix is a periodic string. That is, for each i (2 <= i <= N) we want to know the largest K > 1 (if there is one) such that the prefix of S with length i can be written as AK , that is A concatenated K times, for some string A. Of course, we also want to know the period K.
[align=left]Input[/align]
The input file consists of several test cases. Each test case consists of two lines. The first one contains N (2 <= N <= 1 000 000) – the size of the string S. The second line contains the string S. The input file ends with a line, having the number zero on it.
[align=left]Output[/align]
For each test case, output “Test case #” and the consecutive test case number on a single line; then, for each prefix with length i that has a period K > 1, output the prefix size i and the period K separated by a single space; the prefix sizes must be in increasing order. Print a blank line after each test case.
[align=left]Sample Input[/align]
3
aaa
12
aabaabaabaab
0
[align=left]Sample Output[/align]
Test case #1
2 2
3 3
Test case #2
2 2
6 2
9 3
12 4
[align=left]Recommend[/align]
JGShining | We have carefully selected several similar problems for you: 1711 1686 3746 3068 2203
KMP算法。
这道题考察的是KMP算法中next数组的应用,必须理解透next[]数组代表的含义才能通过它解决这道题。
思路是先构造出 next[] 数组,下标为 i,定义一个变量 j = i - next[i] 就是next数组下标和下标对应值的差,如果这个差能整除下标 i,即 i%j==0 ,则说明下标i之前的字符串(周期性字符串长度为 i)一定可以由一个前缀周期性的表示出来,这个前缀的长度为刚才求得的那个差,即 j,则这个前缀出现的次数为 i/j 。所以最后输出i和i/j即可。
举这道题的第二组输入样例为例:
其next[]数组为:
i 0 1 2 3 4 5 6 7 8 9 10 11 a[i] a a b a a b a a b a a b next[i] -1 0 1 0 1 2 3 4 5 6 7 8
[b]↓[/b]
next[i]值是0或-1的忽略。
注意:由于输出次数太多 (2 <= N <= 1 000 000),建议用printf输出,否则会超时。
代码:
#include <iostream> #include <stdio.h> using namespace std; char a[1000010]; int next[1000010]; int n; void GetNext() //获得a数列的next数组 { int i=0,k=-1; next[0] = -1; while(i<n){ if(k==-1){ next[i+1] = 0; i++;k++; } else if(a[i]==a[k]){ next[i+1] = k+1; i++;k++; } else k = next[k]; } } void DisRes(int num) { int j; printf("Test case #%d\n",num); for(int i=0;i<=n;i++){ if(next[i]==-1 || next[i]==0) //next[i]是-1或0的忽略,说明之前没有周期性前缀 continue; j = i - next[i]; if(i%j==0) //能整除,说明存在周期性前缀 printf("%d %d\n",i,i/j); //输出这个前缀的长度和周期数 } printf("\n"); } int main() { int num = 0; while(scanf("%d",&n)!=EOF){ if(n==0) break; scanf("%s",a); GetNext(); //获得next[]数组 DisRes(++num); //输出结果 } return 0; }
Freecode : www.cnblogs.com/yym2013
相关文章推荐
- (KMP 1.5)hdu 1358 Period(使用next数组来求最小循环节——求到第i个字符的循环节数)
- hdu 1358 Period(KMP之next数组)
- hdu 1358 Period(KMP之next数组)
- hdu 1358 Period(KMP之next数组)
- HDU 1358 Period(next数组+周期+循环节)
- hdu 1358 Period(KMP之next数组)
- hdu 1358 Period(KMP之next数组)
- hdu 1358 Period(KMP之next数组)
- hdu 1358(Period)next数组的运用 计算前i个字符的循环周期 /poj 2406 计算字符串的周期
- hdu 1358 Period(next数组的理解)
- HDu 1358 Period(Next 数组找循环节)
- hdu 1358 Period(KMP之next数组)
- hdu 1358 Period(KMP之next数组)
- hdu 1358 Period(KMP之next数组)
- hdu 1358 Period(KMP之next数组)
- HDU - 1358 Period(KMP next数组)
- 【next数组应用】HDU 1358 Period
- HDU - 1358 Period 【next数组的灵魂掌握】
- hdu 1358 Period(KMP之next数组)
- hdu 1358 Period(KMP之next数组)