1. 程式人生 > >BZOJ_3942_[Usaco2015 Feb]Censoring_KMP

BZOJ_3942_[Usaco2015 Feb]Censoring_KMP

name com include usaco2015 strlen 記錄 字符 let AR

BZOJ_3942_[Usaco2015 Feb]Censoring_KMP

Description

有一個S串和一個T串,長度均小於1,000,000,設當前串為U串,然後從前往後枚舉S串一個字符一個字符往U串裏添加,若U串後綴為T,則去掉這個後綴繼續流程。

Input

The first line will contain S. The second line will contain T. The length of T will be at most that of S, and all characters of S and T will be lower-case alphabet characters (in the range a..z).

Output

The string S after all deletions are complete. It is guaranteed that S will not become empty during the deletion process.

Sample Input

whatthemomooofun
moo

Sample Output

whatthefun
用一個棧來記錄當前匹配到那個字符和那個字符在哪個位置。 然後KMP每次跳nxt即可。 代碼:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 1000050
int nxt[N],ls,lw,a[N],pos[N];
char s[N],w[N];
void get_nxt() {
    int i,j=0;
    for(i=2;i<=lw;i++) {
        while(j&&w[j+1]!=w[i]) j=nxt[j];
        nxt[i]=(w[j+1]==w[i])?++j:0;
    }
}
void work() {
    int i,j,top=0;
    for(i=1;i<=ls;i++) {
        j=pos[top];
        a[++top]=s[i];
        while(j&&w[j+1]!=s[i]) j=nxt[j];
        if(w[j+1]==s[i]) j++;
        if(j==lw) {
            top-=lw;
        }else pos[top]=j;
    }
    for(i=1;i<=top;i++) printf("%c",a[i]);
}
int main() {
    scanf("%s%s",s+1,w+1);
    ls=strlen(s+1); lw=strlen(w+1);
    get_nxt();
    work();
}

BZOJ_3942_[Usaco2015 Feb]Censoring_KMP