3942: [Usaco2015 Feb]Censoring

3942: [Usaco2015 Feb]Censoring

Time Limit: 10 Sec   Memory Limit: 128 MB
Submit: 718   Solved: 371
[ Submit][ Status][ Discuss]

Description

Farmer John has purchased a subscription to Good Hooveskeeping magazine for his cows, so they have plenty of material to read while waiting around in the barn during milking sessions. Unfortunately, the latest issue contains a rather inappropriate article on how to cook the perfect steak, which FJ would rather his cows not see (clearly, the magazine is in need of better editorial oversight).

FJ has taken all of the text from the magazine to create the string S of length at most 10^6 characters. From this, he would like to remove occurrences of a substring T to censor the inappropriate content. To do this, Farmer John finds the _first_ occurrence of T in S and deletes it. He then repeats the process again, deleting the first occurrence of T again, continuing until there are no more occurrences of T in S. Note that the deletion of one occurrence might create a new occurrence of T that didn't exist before.

Please help FJ determine the final contents of S after censoring is complete

有一个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

HINT

Source

[ Submit][ Status][ Discuss]

这一题的题目意思还是比较容易明白的,嗯。

我们就用一个栈来模仿题目所示的操作,匹配可用KMP加速。

如果匹配上了就弹栈(注意记录S每个位置最大匹配到T的哪一位,方便处理)

AC之路:

这道题有时因为一些奇怪的原因会把WA变成OLE,其实也没问题(反正都是没AC,在这里提醒一下大家)

上代码:(看了代码大家可能就会清楚一些了,码风有点……)

#include<bits/stdc++.h>
using namespace std;
const int N = 1000005;
char s1[N],s2[N],sta[N];
int nxt[N],_[N],top,len1,len2;
void get(){//标准KMP,构造next(fail)数组
    int j=0;
    for(int i=1;i<len2;i++){
        while(j>0&&s2[j+1]!=s2[i+1]) j=nxt[j];
        if(s2[j+1]==s2[i+1]) j++;
        nxt[i+1]=j;
    }
}
int main(){
    scanf("%s",s1+1);//这里s1+1表示从s1[1]开始读入,方便处理。。
    scanf("%s",s2+1);//同理
    len1=strlen(s1+1);
    len2=strlen(s2+1);
    get();
    int j=0;
    for(int i=0;i<len1;i++){//相当于匹配,有点难理解,大家可以仔细想一想。
        while(j>0&&s2[j+1]!=s1[i+1]) j=nxt[j];
        sta[++top]=s1[i+1];//模拟栈
        if(s2[j+1]==s1[i+1]) j++;
        if(j==len2){
             top-=len2;//弹栈
             j=_[top];//重新(也不完全是)匹配
        } else _[top]=j;//记录当前位最多匹配多少
    }
    for(int i=1;i<=top;i++) printf("%c",sta[i]);//输出
    return 0;
}
还算短吧,( ̄▽ ̄)"。


猜你喜欢

转载自blog.csdn.net/qq_38944163/article/details/81014977