zoukankan      html  css  js  c++  java
  • B3942 Censoring

    爆炸入口

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

    这道题确乎是个很好的联系kmp的题目

    结合了栈的思想。通过栈保留匹配时的失配指针的位置,达到分段删除的效果,即可以通过删去中间若干个T串,使得被删去左右两端可以拼成T。

    同时也因为栈,使得我们在输出的更加方便。结束时,在栈中的元素一定是无法删除的元素。而且是有序的(输入顺序,从下标小的开始),直接输出即可以。


    怎么使用栈呢?

    对于每一个匹配串中的字符。我们一一将其入栈,然后保留以当前元素为结束kmp的失配指针,方便我们拼接。然后继续和普通的kmp一样匹配。

    每次从栈顶拿一个元素出来(一定是栈),根据已经保留的失配指针继续匹配。

    匹配到时,就立马退栈。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    const int manx=1000100;
    int stack[manx],top;
    int f[manx],fail[manx];
    char a[manx],b[manx];
    int main()
    {
    	int n,m;
    	scanf("%s%s",a,b);
    	n=strlen(a),m=strlen(b);
    	int k=0;
    	for(int i=1;i<m;i++)
    	{
    		while(k&&b[i]!=b[k])	k=fail[k];
    		if(b[i]==b[k])	fail[i+1]=++k;//处理失配指针
    	}
    	for(int i=0;i<n;i++)//一样的匹配
    	{
    		k=f[stack[top]];//每次从栈顶拿一个元素,因为第一个元素是0,所以说我就没有写将0入栈
    		while(k&&a[i]!=b[k])	k=fail[k];//跳失配
    		if(a[i]==b[k])	++k;
    		if(k==m)	top-=(m-1);//匹配到时,退栈,一定要处理好退栈的元素个数,我这里i还没有入栈,所以只退栈m-1个元素
    		else	f[i]=k,stack[++top]=i;//保留fail,进栈
    	}
    	for(int i=1;i<=top;i++)
    		printf("%c",a[stack[i]]);//输出
    }
    
  • 相关阅读:
    CodeForces Gym 100500A A. Poetry Challenge DFS
    CDOJ 486 Good Morning 傻逼题
    CDOJ 483 Data Structure Problem DFS
    CDOJ 482 Charitable Exchange bfs
    CDOJ 481 Apparent Magnitude 水题
    Codeforces Gym 100637G G. #TheDress 暴力
    Gym 100637F F. The Pool for Lucky Ones 暴力
    Codeforces Gym 100637B B. Lunch 找规律
    Codeforces Gym 100637A A. Nano alarm-clocks 前缀和
    TC SRM 663 div2 B AABB 逆推
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9224173.html
Copyright © 2011-2022 走看看