标签:
题目链接:http://poj.org/problem?id=2752
Description
Input
Output
Sample Input
ababcababababcabab aaaaa
Sample Output
2 4 9 18 1 2 3 4 5
本题求的是整个字符串中前后缀相同的子串,输出的是他们的长度。
通过这个题又加深了对KMP的pre数组的认识:
pre可以认为是(如pre[n] = k)字符串0-n中前k个字符和后k个字符相同。即前缀和后缀相同。
n != 0,我们可以认为只要pre[n] != 0,那么就存在前后缀相同的子串,长度恰好是k。
(PS:“遍历”的过程有点像并查集)
PPS:注意输出要按照"increasing number"
代码如下:
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <algorithm> 5 #include <iostream> 6 #include <cmath> 7 #include <queue> 8 #include <map> 9 #include <stack> 10 #include <list> 11 #include <vector> 12 13 using namespace std; 14 15 const int maxn = 400010; 16 17 int nb; 18 char b[maxn]; 19 int pre[maxn]; 20 21 void getpre(char *b, int *pre) { 22 int j, k; 23 pre[0] = -1; 24 j = 0; 25 k = -1; 26 while(j < nb) { 27 if(k == -1 || b[j] == b[k]) { 28 j++; 29 k++; 30 pre[j] = k; 31 } 32 else { 33 k = pre[k]; 34 } 35 } 36 } 37 38 int main() { 39 // freopen("in", "r", stdin); 40 while(gets(b) && strlen(b)) { 41 int ans[maxn]; 42 int cnt = 0; 43 nb = strlen(b); 44 getpre(b, pre); 45 while(pre[nb] != -1) { 46 // printf("%d ", nb); 47 ans[cnt++] = nb; 48 nb = pre[nb]; 49 } 50 for(int i = cnt-1; i >= 0; i--) { 51 printf("%d ", ans[i]); 52 } 53 printf("\n"); 54 } 55 }
[POJ2752]Seek the Name, Seek the Fame
标签:
原文地址:http://www.cnblogs.com/vincentX/p/4758339.html