题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1358
主要考查KMP算法next数组本质的理解。len - len[len]为循环节的大小~~~
代码如下:
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 5 const int N = 1000002; 6 char str[N]; 7 int next[N]; 8 9 void get_next(int len) 10 { 11 int i = 0; 12 int j = -1; 13 next[i] = -1; 14 while(i < len) 15 { 16 if(j == -1 || str[i] == str[j]) 17 { 18 i++; 19 j++; 20 next[i] = j; 21 } 22 else 23 { 24 j = next[j]; 25 } 26 } 27 } 28 29 int main() 30 { 31 int n; 32 int k = 0; 33 while(scanf("%d", &n) != EOF && n != 0) 34 { 35 scanf("%s", str); 36 get_next(n); 37 k++; 38 printf("Test case #%d\n", k); 39 for(int i = 2; i <= n; i++) 40 { 41 int x = i - next[i]; 42 if((i % x == 0) && i / x != 1) 43 { 44 printf("%d %d\n", i, i / x); 45 } 46 } 47 printf("\n"); 48 } 49 return 0; 50 }
参考别人的代码:
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 5 const int N = 1000002; 6 char str[N]; 7 int next[N]; 8 9 void get_next(int len) 10 { 11 int i; 12 int j = 0; 13 for(next[1] = 0, i = 2; i <= len; i++) 14 { 15 while(j && str[i] != str[j + 1]) 16 { 17 j = next[j]; 18 } 19 if(str[i] == str[j + 1]) 20 { 21 j++; 22 } 23 next[i] = j; 24 } 25 } 26 27 int main() 28 { 29 int n; 30 int k = 1; 31 while(scanf("%d", &n) != EOF && n != 0) 32 { 33 scanf("%s", str + 1); 34 get_next(n); 35 printf("Test case #%d\n", k++); 36 for(int i = 2; i <= n; i++) 37 { 38 if(i % (i - next[i]) == 0 && i / (i - next[i]) != 1) 39 { 40 printf("%d %d\n", i, i / (i - next[i])); 41 } 42 } 43 printf("\n"); 44 } 45 return 0; 46 }