codeforces 1200E

本文介绍了一道编程题,利用KMP算法寻找两个合并字符串中的最长相同前缀后缀。通过构造新字符串并求解其失配数组,确定插入位置以保持最长匹配。
摘要由CSDN通过智能技术生成

c f cf cf上的题就是不板,综合考察对 k m p kmp kmp的运用
题目链接

题目大意

给定 n n n个字符串,从左到右依次把两个字符串合成一个,每两个合并的字符串,需要你找到最大的 i i i,满足前字符串长度为 i i i的后缀等于后字符串长度为 i i i的前缀,把后字符串第 i i i位以后的字符接到前字符串上,若没有相同的前后缀则直接拼接,输出最终结果

思路

题目要求找到相同的前缀和后缀,立刻想到要用 k m p kmp kmp,但是 k m p kmp kmp是在一个字符串内用的,所以每到两个字符串要链接时,我们先构造一个合起来的字符串 s s s,对合起来的字符串进行 g e t get get_ p m t pmt pmt,找到失配数组 p m t pmt pmt,要找的相同的前后缀数量就是 p m t [ s . s i z e ( ) − 1 ] pmt[s.size()-1] pmt[s.size()1],注意一点:为了防止越过过度匹配超过自身长度,我们要在两个要链接的字符串中加一段乱码,如匹配 101 101 101 010 010 010

ACcode

#include<bits/stdc++.h>

using namespace std;

const int M = 1e6 + 9;
int pmt[M];

void get_pmt(const string& p) {
    pmt[0] = 0;pmt[1] = 0;
    for (int i = 1, j = 0;i < p.size();i++) {
        while (j && p[i] != p[j])j = pmt[j - 1];
        if (p[i] == p[j])j++;
        pmt[i] = j;
    }
}

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n;cin >> n;
    string ans;cin >> ans;
    string s;
    //cout << n << ' ' << ans;
    for (int i = 2;i <= n;i++) {
        cin >> s;
        int len = min(s.size(), ans.size());
        string ss = s + "(@#$%^&*!~~?><" + ans.substr(ans.size() - len, len);
        get_pmt(ss);
        //cout << ss << '\n';
        for (int j = pmt[ss.size() - 1];j < s.size();j++) ans += s[j];
    }
    cout << ans << '\n';
    return 0;
}
  • 56
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值