洛谷P4824 [USACO15FEB] Censoring S 题解

洛谷P4824 [USACO15FEB] Censoring S 题解

题目链接:P4824 [USACO15FEB] Censoring S

题意:给出字符串 t t t s s s ,删除在 t t t 中第一次出现的子串 s s s ,并重复这个过程(在产生的新串 t ’ t’ t 上继续删除操作),求最后的结果

匹配问题可以用KMP来解决

怎么处理删除操作呢?

可以观察下样例

注意到删除子串后,在删除的子段后继续匹配可能需要该子段前的已经算出(显然)的匹配值

那么我们可以用两个栈分别维护KMP的匹配值和答案

在每次删除后我们只要让top-=m即可,其中m s s s 的长度

时间复杂度 O ( ∣ t ∣ + ∣ s ∣ ) O(|t|+|s|) O(t+s)

代码如下

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define MAXN (int)(1e6+5)
int n,m,fail[MAXN],top,stk[MAXN];
char t[MAXN],s[MAXN],ans[MAXN];
signed main()
{
	scanf("%s\n%s\n",t+1,s+1);
	n=strlen(t+1);m=strlen(s+1);
	for(int i=2,j=0; i<=m; i++)
	{
		while(j&&s[i]!=s[j+1])j=fail[j];
		if(s[i]==s[j+1])++j;
		fail[i]=j;
	}
	for(int i=1,j=0; i<=n; i++)
	{
		while(j&&t[i]!=s[j+1])j=fail[j];
		if(t[i]==s[j+1])++j;
		stk[++top]=j;
		ans[top]=t[i];
		if(j==m)top-=m,j=stk[top];
	}
	ans[top+1]='\0'; // 不要忘了这个哦!
	printf("%s",ans+1);
	return 0;
}

当然这个题还有个加强版

做法类似,只不过变成多模式串匹配了而已

题解在此

转载请说明出处

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值