POJ2774 Long Long Message

题目链接:http://poj.org/problem?id=2774

The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to him these days: his mother is getting ill. Being worried about spending so much on railway tickets (Byterland is such a big country, and he has to spend 16 shours on train to his hometown), he decided only to send SMS with his mother...

题目大意:给两个字符串,求出该两个字符串中公共子串的最大长度。

思路:

1.其实我认为可以枚举第一个字符串的各个子串,然后用kmp求得公共子串的最大长度的。但好像没人这么写,是哪儿有问题吗? 如果有有缘人看到了并且知道为什么 ,欢迎加我QQ:709401953 ,帮我解答 请你吃饭饭。

2.用一个不会出现的字符连接两个字符串,对连接后的字符串跑一遍height数组,height数组的含义是字典序排名为 i 与排名为 i - 1的后缀的最长公共前缀的长度。

跑height数组模板:

 1 void get_H()
 2 {
 3     int k = 0;
 4     for(int i = 1; i <= len; i ++)
 5         rank[sa[i]] = i;
 6     for(int i = 1; i <= len; i ++)
 7     {
 8         if(k)
 9             k --;
10         int j = sa[rank[i] - 1];
11         while(s[i + k] == s[j + k])
12             k ++;
13         height[rank[i]] = k;
14     }
15 }
height数组

AC代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #define mem(a, b) memset(a, b, sizeof(a))
 5 const int MAXN = 1e5 + 10;
 6 using namespace std;
 7 
 8 char s1[MAXN], s2[MAXN], s[2 * MAXN];
 9 int len, size;
10 int rank[2 * MAXN], sa[2 * MAXN], tax[2 * MAXN], tp[2 * MAXN], height[2 * MAXN], p;
11 
12 void Q_sort()
13 {
14     for(int i = 0; i <= size; i ++)    tax[i] = 0;
15     for(int i = 1; i <= len; i ++)    tax[rank[i]] ++;
16     for(int i = 1; i <= size; i ++)    tax[i] += tax[i - 1];
17     for(int i = len; i >= 1; i --)    sa[tax[rank[tp[i]]] --] = tp[i];
18 }
19 
20 void get_H()
21 {
22     int k = 0;
23     for(int i = 1; i <= len; i ++)
24         rank[sa[i]] = i;
25     for(int i = 1; i <= len; i ++)
26     {
27         if(k)
28             k --;
29         int j = sa[rank[i] - 1];
30         while(s[i + k] == s[j + k])
31             k ++;
32         height[rank[i]] = k;
33     }
34 }
35 
36 void get_SA()
37 {
38     for(int i = 1; i <= len; i ++)    rank[i] = s[i], tp[i] = i;
39     Q_sort();
40     for(int w = 1; w <= len; w *= 2)
41     {
42         p = 0;
43         for(int i = 1; i <= w; i ++)    tp[++ p] = len - w + i;
44         for(int i = 1; i <= len; i ++)    if(sa[i] > w) tp[++ p] = sa[i] - w;
45         Q_sort();
46         swap(tp, rank);//tp数组无用 继承上一轮rank排名
47         rank[sa[1]] = p = 1;
48         for(int i = 2; i <= len; i ++)
49             rank[sa[i]] = (tp[sa[i - 1]] == tp[sa[i]] && tp[sa[i - 1] + w] == tp[sa[i] + w]) ? p : ++ p;
50         size = p;
51         if(p >= len)
52             break;
53     }
54     get_H();
55 }
56 
57 int main()
58 {
59     scanf("%s%s", s1 + 1, s2 + 1);
60     int len1 = strlen(s1 + 1), len2 = strlen(s2 + 1);
61     int cnt = 0;
62     for(int i = 1; i <= len1; i ++)
63         s[++ cnt] = s1[i];
64     s[++ cnt] = '#';  //用一个不会出现的字符连接两个字符串。 
65     for(int i = 1; i <= len2; i ++)
66         s[++ cnt] = s2[i];
67     len = strlen(s + 1), size = 130;
68     get_SA();
69     int ans = 0;
70     for(int i = 2; i <=len; i ++)
71     {
72         if(sa[i - 1] <= len1 && sa[i] > len1 + 1)
73             ans = max(ans, height[i]);
74         else if(sa[i - 1] > len1 + 1 && sa[i] <= len1)
75             ans = max(ans, height[i]);
76     }
77     printf("%d\n", ans);
78     return 0;
79 }
POJ2774

 

posted @ 2019-07-19 18:40  缘未到  阅读(124)  评论(0编辑  收藏  举报