【USACO】Censoring(Silver)

题目描述

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

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

Please help FJ determine the final contents of S after censoring iscomplete.

 输入

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 Twill be lower-case alphabet characters (in the range a..z).

 输出

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

 样例输入

whatthemomooofun

moo

样例输出

whatthefun

解题思路:这道题目是KMP的变形。将模版改一下即可。

代码:(请不要直接拷贝哦)

#include <cstdio>
#include <cstring>
char s[1000005],t[1000005],ans[1000005];
int next[1000005],pos[1000005];
int lens,lent,top=0;
using namespace std;
inline void getnext()//KMP的求next数组
{
	next[0]=-1;
	int i=0,j=-1;
	while (i<lent)
	  if ((j==-1)||(t[i]==t[j])) next[++i]=++j;
	    else j=next[j];
}
int main()
{
	scanf("%s",&s);
	scanf("%s",&t);
	lens=strlen(s);
	lent=strlen(t);
	getnext();
	int j=0;
	for (int i=0;i<lens;i++)
	{
		ans[top++]=s[i];//ans数组相当于是一个栈,用来将答案字母一个一个堆起来
		while ((j!=-1)&&(t[j]!=ans[top-1])) j=next[j];//不断地将字串往右挪
		if (t[j]==ans[top-1]) j++;//如果相同,可以比较下一个字符
		if (j==-1) j=0;//如果j还是-1的话,会影响到下面的程序,所以就将它改成0
		pos[top-1]=j;//记录当前这个字符已经匹配到子串的那个字符了
		if (j==lent) //子串是否成功完全匹配
		{//如果成功了
			top-=lent;//栈顶往下放,相当于去掉了这个子串
			j=pos[top-1];//回溯
		}
	}
	for (int i=0;i<top;i++)  putchar(ans[i]);
	printf("\n");
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值