1. 程式人生 > >【USACO】Censoring(Silver)

【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;
}