CF1200ECompress Words

一、题目描述

  

 

 二、解题思路

  这个题目思路不难,但是容易坑你,就是中间为了防止特殊情况发生需要加上1个特殊字符,防止判断错误。(等会再说)

  这个题目要我们求拼接后的单词,但是前一个单词的后缀和后一个单词的前缀的相重合的部分不再相加,所以我们想到了kmp算法,用string把输入串接上目前答案串,写个kmp得到个next数组,最后一个字符的next一定就是重合的最大部分,只需要把输入串中重合的部分拼接到当前答案串即可。但是我一直wa。。。。

    上cf一看错,发现我少考虑了一种特殊的情况,就是当答案串是aba 目前串是abab,这时候最后一个字符的next会是6,出错了对吧?,因为我们目前串最长都只有3,哪来的相似度为6?怎么解决这个问题呢?我们只需要在这两个字符串拼接的时候在中间弄个特殊符号就可以了。(比如说$)

三、代码实现 

 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 const int maxn = 1e6;
 4 char ans[maxn + 10];
 5 int nextval[maxn + 10];
 6 void kmp(char *temp)
 7 {
 8     int i,j;
 9     i = 0,j = -1;
10     int len = strlen(temp);
11     nextval[0] = -1;
12     while(i < len) {
13         if(j == -1 || temp[i] == temp[j]) {
14             i++,j++;
15             nextval[i] = j;
16         }
17         else 
18             j = nextval[j];
19     }
20 }
21 int main()
22 {
23     int n;
24     cin >> n;
25     cin >> ans;
26     int anslen = strlen(ans);
27     for(int i = 2;i <= n;i++){
28         char s[2 * maxn + 10];
29         cin >> s;
30         int slen = strlen(s);
31         int top = slen;
32         int mlen = min(slen,anslen);
33         s[top++] = '$';
34         for(int j = 0;j < mlen;j++)
35             s[top++] = ans[anslen - (mlen - j)]; 
36         kmp(s);
37         for(int j = nextval[top];j < slen;j++)
38             ans[anslen++] = s[j];
39     }
40     cout << ans;
41     return 0;
42 }
posted @ 2022-02-08 20:43  scannerkk  阅读(36)  评论(0)    收藏  举报