Hdu 1358 Period (KMP 求最小循环节)
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1358
题目描述:
给出一个字符串S,输出S的前缀能表达成Ak的所有情况,每种情况输出前缀的结束位置和k。
解题思路:
打表算出next数组,然后对位置i求循环节,如果满足 i % (i - Next[i]) == 0 && Next[i] != 0,所对应的循环节(i - Next[i]), 循环次数是i / (i - Next[i])
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 8 #define LL long long 9 #define maxn 1000010 10 #define mod 100000007 11 12 char a[maxn]; 13 int Next[maxn], m; 14 15 void get_next (char a[]) 16 { 17 int i, j; 18 Next[0] = j = -1; 19 i = 0; 20 21 while (i < m) 22 { 23 while (j!=-1 && a[i]!=a[j]) 24 j = Next[j]; 25 26 Next[++ i] = ++j; 27 } 28 } 29 30 void solve () 31 { 32 for (int i=1; i<=m; i++) 33 { 34 if (Next[i] != 0 && i % (i - Next[i]) == 0) 35 printf ("%d %d\n", i, i / (i - Next[i])); 36 } 37 printf ("\n"); 38 } 39 int main () 40 { 41 int l = 0; 42 while (scanf ("%d", &m), m) 43 { 44 scanf ("%s", a); 45 get_next (a); 46 47 printf ("Test case #%d\n", ++l); 48 49 solve (); 50 } 51 return 0; 52 } 53 /* 54 3 55 aabccb 56 */
本文为博主原创文章,未经博主允许不得转载。