1. 程式人生 > >【USACO15FEB】審查(黃金)Censoring (Gold)

【USACO15FEB】審查(黃金)Censoring (Gold)

clu amp del lease sed better n) truct mos

題目描述

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^5 characters. He has a list of censored words t_1 ... t_N that he wishes to delete from S. To do so Farmer John finds the earliest occurrence of a censored word in S (having the earliest start index) and removes that instance of the word from S. He then repeats the process again, deleting the earliest occurrence of a censored word from S, repeating until there are no more occurrences of censored words in S. Note that the deletion of one censored word might create a new occurrence of a censored word that didn‘t exist before.

Farmer John notes that the censored words have the property that no censored word appears as a substring of another censored word. In particular this means the censored word with earliest index in S is uniquely defined.

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

FJ把雜誌上所有的文章摘抄了下來並把它變成了一個長度不超過10^5的字符串S。他有一個包含n個單詞的列表,列表裏的n個單詞記為t_1...t_N。他希望從S中刪除這些單詞。

FJ每次在S中找到最早出現的列表中的單詞(最早出現指該單詞的開始位置最小),然後從S中刪除這個單詞。他重復這個操作直到S中沒有列表裏的單詞為止。註意刪除一個單詞後可能會導致S中出現另一個列表中的單詞

FJ註意到列表中的單詞不會出現一個單詞是另一個單詞子串的情況,這意味著每個列表中的單詞在S中出現的開始位置是互不相同的

請幫助FJ完成這些操作並輸出最後的S

輸入輸出格式

輸入格式:

The first line will contain S.

The second line will contain N, the number of censored words. The next N lines contain the strings t_1 ... t_N. Each string will contain lower-case alphabet characters (in the range a..z), and the combined lengths of all these strings will be at most 10^5.

輸出格式:

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

輸入輸出樣例

輸入樣例#1:
begintheescapexecutionatthebreakofdawn 
2 
escape 
execution 
輸出樣例#1:
beginthatthebreakofdawn 


題解:

將n個單詞建Trie,開一個棧記錄答案和走的順序,然後走到有標記的地方就直接把棧的top減dis(dis為該節點到root的距離)
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 using namespace std;
 8 const int LL=100005;
 9 char s[LL],h[LL];
10 struct node
11 {
12     int next[27],cnt,dis;
13 }a[LL];
14 int fail[LL],num=0,root=0;
15 void Clear()
16     {
17         a[num].cnt=0;
18         a[num].dis=0;
19         for(int i=0;i<=26;i++)a[num].next[i]=0;
20     }
21 void add()
22     {
23         scanf("%s",h);
24         int p=root;
25         for(int i=0,ls=strlen(h);i<ls;i++)
26             {
27                 if(a[p].next[h[i]-a])a[a[p].next[h[i]-a]].dis=a[p].dis+1,p=a[p].next[h[i]-a];
28                 else
29                     {
30                         a[p].next[h[i]-a]=++num;
31                         Clear();
32                         a[num].dis=a[p].dis+1;
33                         p=num;
34                     }
35             }
36         a[p].cnt++;
37     }
38 void getfail()
39     {
40         queue<int>q;
41         q.push(root);
42         int p,v,to;
43         while(!q.empty())
44             {
45                 p=q.front();q.pop();
46                 for(int i=0;i<=26;i++)
47                     {
48                         if(!a[p].next[i])
49                             {
50                                 if(a[fail[p]].next[i])a[p].next[i]=a[fail[p]].next[i];
51                                 continue;
52                             }
53                         v=fail[p];
54                         while(v)
55                             {
56                                 if(a[v].next[i])break;
57                                 v=fail[v];
58                             }
59                         to=a[p].next[i];
60                         if(a[v].next[i] && a[v].next[i]!=a[p].next[i])fail[to]=a[v].next[i];
61                         q.push(to);
62                     }
63             }
64     }
65 int st[LL];char ans[LL];int top=0;
66 void pf()
67     {
68         int u;
69         int p=root;
70         st[++top]=root;
71         for(int i=0,ls=strlen(s);i<ls;i++)
72             {
73                 u=s[i]-a;
74                 while(!a[p].next[u] && p)p=fail[p];
75                 p=a[p].next[u];
76                 st[++top]=p;ans[top]=s[i];
77                 if(a[p].cnt)
78                     {
79                         top-=a[p].dis;
80                         p=st[top];
81                     }
82             }
83     }
84 int main()
85     {
86         //freopen("pp.in","r",stdin);
87         Clear();
88         scanf("%s",s);
89         int n;
90         scanf("%d",&n);
91         for(int i=1;i<=n;i++)add();
92         getfail();
93         pf();
94         for(int i=2;i<=top;i++)printf("%c",ans[i]);
95         printf("\n");
96         return 0;
97     }




【USACO15FEB】審查(黃金)Censoring (Gold)