Censoring「USACO 2015 Feb」

题目描述

有一个S串和一个T串,长度均小于1,000,000,设当前串为U串,然后从前往后枚举S串一个字符一个字符往U串里添加,若U串后缀为T,则去掉这个后缀继续流程。

输入格式

包含两行,第一行为S串,第二行为T串

输出格式

输出题目要求的字符串序列

样例

输入样例

whatthemomooofun
moo

输出样例

whatthefun

讲一下题意:
拿样例模拟一下,u往后添加一直到"whatthemomoo"时把末尾的"moo"删掉->"whattemo",之后又添加一个“o”,注意是这
whatthemomoo(o)fun个“o”。变成"whatthemoo",再把moo删掉变成"whatthe"。最后加上fun,所以输出是"whattefun"。

这道题其实就是一道模拟+kmp(默认你们都会kmp)。用一个数组f纪录主串每个位置i它的后缀和模式串的前缀的最大匹配长度。删除就是回到i-m(模式串长度),然后j(匹配长度)回到fi-m即可。
代码也很好写。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n, m, nxt[1000100], f[1000100], l;
char u[1000100], s[1000100], t[1000100];
int main() {
    scanf("%s%s", s + 1, t + 1);
    n = strlen(s + 1), m = strlen(t + 1);
    for (int i = 2, j = 0; i <= m; i++) {
        while (j && t[i] != t[j + 1]) j = nxt[j];
        if (t[i] == t[j + 1]) j++;
        nxt[i] = j;
    }
    for (int i = 1, j = 0; i <= n; i++) {
        u[++l] = s[i];
        while (j && u[l] != t[j + 1]) j = nxt[j];
        if (u[l] == t[j + 1]) j++;
        f[l] = j;
        if (j == m) l -= m, j = f[l];//删除操作
    }
    for (int i = 1; i <= l; i++) cout << u[i];
    return 0;
}
 



原文地址:https://www.cnblogs.com/zcr-blog/p/11793866.html