1269. Obscene Words Filter
Time limit: 0.5 second
Memory limit: 8 MB
There is a problem to check messages of web-board visitors for the obscene words. Your elder colleagues commit this problem to you. You are to write a program, which check if there is at least one obscene word from the given list in the given text as a substring.
Input
The first line consists of integer n (1 ≤ n ≤ 10000) — an amount of words. The next n lines contain the list of words that we can’t allow to use in our well-educated society. A word may contain any symbol but the ones with codes 0, 10 and 13. The length of each word doesn’t exceed 10000 symbols. The total list of words doesn’t exceed 100 KB. Then there is an integer m — the number of lines of the text. A size of the text doesn’t exceed 900 KB.
Output
the number of line and the number of position separated with a space, where an obscene word occurs for the first time. If there are no obscene words, output “Passed”.
Sample
input | output |
---|---|
5 dear sweetie angel dream baby 8 Had I the heavens‘ embroidered cloths, Enwrought with golden and silver light, The blue and the dim and the dark cloths Of night and light and the half-light, I would spread the cloths under your feet: But I, being poor, have only my dreams; I have spread my dreams under your feet; Tread softly because you tread on my dreams. |
6 33 |
Problem Author: Pavel Atnashev
Problem Source: Ural State University championship, October 25, 2003
Tags: string algorithms (hide tags for unsolved problems)
Difficulty: 832
题意:问在文章中第一次出现禁忌单词的地方
分析:AC自动机,但这题卡时间卡内存
链表?边目录?No,卡时间
数组?对了一半,卡空间
所以,只能动态的分配孩子的空间
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 #define For(i, s, t) for(int i = (s); i <= (t); i++) 6 #define INF (1000000001) 7 8 const int N = 150010; 9 struct TreeType 10 { 11 char C; 12 int Next; 13 int *Child; 14 unsigned short Len, CLen, Size; 15 } Tree[N]; 16 //int First[N], To[N], Next[N], Tot; 17 int n, m, Cnt, Ans = INF; 18 char Str[N * 6]; 19 int Q[N]; 20 21 /*inline void Insert(int u, int v) 22 { 23 Tot++; 24 To[Tot] = v, Next[Tot] = First[u]; 25 First[u] = Tot; 26 }*/ 27 28 inline void Updata(TreeType &T) 29 { 30 T.Size += 3; 31 int *p = new int[T.Size + 1]; 32 for(int i = 0; i < T.CLen; i++) p[i] = T.Child[i]; 33 delete []T.Child; 34 T.Child = p; 35 } 36 37 inline void Ins(char *Str) 38 { 39 int Length = strlen(Str + 1), x = 0, Tab; 40 bool Flag; 41 For(i, 1, Length) 42 { 43 Flag = 0; 44 /*for(Tab = First[x]; Tab; Tab = Next[Tab]) 45 if(Tree[To[Tab]].C == Str[i]) 46 { 47 Flag = 1; 48 x = To[Tab]; 49 break; 50 }*/ 51 for(Tab = 0; Tab < Tree[x].CLen; Tab++) 52 if(Tree[Tree[x].Child[Tab]].C == Str[i]) 53 { 54 Flag = 1, x = Tree[x].Child[Tab]; 55 break; 56 } 57 if(!Flag) 58 { 59 //Insert(x, ++Cnt); 60 if(Tree[x].CLen >= Tree[x].Size) Updata(Tree[x]); 61 Tree[x].Child[Tree[x].CLen++] = ++Cnt; 62 Tree[Cnt].C = Str[i], x = Cnt; 63 } 64 } 65 Tree[x].Len = Length; 66 } 67 68 inline void Input() 69 { 70 scanf("%d", &n); 71 getchar(); 72 For(i, 1, n) 73 { 74 gets(Str + 1); 75 Ins(Str); 76 } 77 } 78 79 inline void Build() 80 { 81 int Head = 1, Tail = 0; 82 int u, v, Tab, k, vv; 83 //for(Tab = First[0]; Tab; Tab = Next[Tab]) 84 for(Tab = 0; Tab < Tree[0].CLen; Tab++) 85 Q[++Tail] = Tree[0].Child[Tab]; 86 while(Head <= Tail) 87 { 88 u = Q[Head++]; 89 //for(Tab = First[u]; Tab; Tab = Next[Tab]) 90 for(Tab = 0; Tab < Tree[u].CLen; Tab++) 91 { 92 v = Tree[u].Child[Tab]; 93 if(!v) continue; 94 //for(k = First[Tree[u].Next]; k; k = Next[k]) 95 for(k = 0; k < Tree[Tree[u].Next].CLen; k++) 96 if(Tree[vv = Tree[Tree[u].Next].Child[k]].C == Tree[v].C) 97 { 98 Tree[v].Next = vv; 99 if(Tree[v].Len < Tree[vv].Len) 100 Tree[v].Len = Tree[vv].Len; 101 break; 102 } 103 Q[++Tail] = v; 104 } 105 } 106 } 107 108 inline void Solve() 109 { 110 //printf("%d\n", Cnt); 111 Build(); 112 scanf("%d", &m), getchar(); 113 int Length, x, Tab; 114 bool Flag; 115 For(Now, 1, m) 116 { 117 gets(Str + 1); 118 Length = strlen(Str + 1), x = 0; 119 For(i, 1, Length) 120 { 121 do 122 { 123 Flag = 0; 124 //for(Tab = First[x]; Tab; Tab = Next[Tab]) 125 for(Tab = 0; Tab < Tree[x].CLen; Tab++) 126 if(Tree[Tree[x].Child[Tab]].C == Str[i]) 127 { 128 x = Tree[x].Child[Tab], Flag = 1; 129 break; 130 } 131 if(!Flag) 132 { 133 x = Tree[x].Next; 134 continue; 135 } 136 if(Tree[x].Len) 137 { 138 if(Ans > i - Tree[x].Len + 1) Ans = i - Tree[x].Len + 1; 139 } 140 break; 141 } while(x); 142 143 } 144 if(Ans != INF) 145 { 146 printf("%d %d\n", Now, Ans); 147 return; 148 } 149 } 150 printf("Passed\n"); 151 } 152 153 int main() 154 { 155 freopen("F.in", "r", stdin); 156 freopen("F.out", "w", stdout); 157 Input(); 158 Solve(); 159 return 0; 160 }