HDU 2896 病毒侵袭
HDU 2896 病毒侵袭
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Problem Description - 题目描述
当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻。。。。在这样的时刻,人们却异常兴奋——我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事儿啊~~
但网路上总有那么些网站,开始借着民众的好奇心,打着介绍日食的旗号,大肆传播病毒。小t不幸成为受害者之一。小t如此生气,他决定要把世界上所有带病毒的网站都找出来。当然,谁都知道这是不可能的。小t却执意要完成这不能的任务,他说:“子子孙孙无穷匮也!”(愚公后继有人了)。
万事开头难,小t收集了好多病毒的特征码,又收集了一批诡异网站的源码,他想知道这些网站中哪些是有病毒的,又是带了怎样的病毒呢?顺便还想知道他到底收集了多少带病毒的网站。这时候他却不知道何从下手了。所以想请大家帮帮忙。小t又是个急性子哦,所以解决问题越快越好哦~~
Input - 输入 |
Output - 输出 |
第一行,一个整数N(1<=N<=500),表示病毒特征码的个数。 |
第一行,一个整数N(1<=N<=500),表示病毒特征码的个数。 |
Sample Input - 输入样例 |
Sample Output - 输出样例 |
3 |
web 1: 1 2 3 |
【题解】
普通的AC自动机。多开辟一个数组保存初始状态即可,唯一感觉有点坑的就是输出total: X后还要来个回车,不然会PE。
【代码 C++】
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 int tr[100005][128], iTR, fail[100005], cnt[100005], cnt2[100005]; 6 int opt[505], iOP; 7 8 void build(){ 9 int n; 10 scanf("%d", &n), getchar(); 11 int i, j, k; 12 char word[205]; 13 for (i = 1; i <= n; ++i){ 14 gets(word); 15 for (j = k = 0; word[j]; ++j){ 16 if (!tr[k][word[j]]) tr[k][word[j]] = ++iTR; 17 k = tr[k][word[j]]; 18 } 19 cnt2[k] = i; 20 } 21 } 22 void setFail(){ 23 std::queue<int> q; 24 int i, j, now; 25 for (i = 0; i < 128; ++i) if (tr[0][i]) q.push(tr[0][i]); 26 while (!q.empty()){ 27 now = q.front(); q.pop(); 28 for (i = 0; i < 128; ++i){ 29 if (j = tr[now][i]) q.push(j), fail[j] = tr[fail[now]][i]; 30 else tr[now][i] = tr[fail[now]][i]; 31 } 32 } 33 } 34 void fid(){ 35 memcpy(cnt, cnt2, sizeof(cnt2)); 36 int i, j, temp; 37 char text[10005]; gets(text); 38 for (i = j = iOP = 0; text[i]; ++i){ 39 j = tr[j][text[i]]; 40 for (temp = j; ~cnt[temp]; temp = fail[temp]){ 41 if (cnt[temp]) opt[iOP++] = cnt[temp]; 42 cnt[temp] = -1; 43 } 44 } 45 std::sort(opt, opt + iOP); 46 } 47 int main(){ 48 build(); 49 setFail(); 50 int i = 1, j, m, total = 0; 51 for (scanf("%d", &m), getchar(); i <= m; ++i){ 52 fid(); 53 if (iOP){ 54 ++total; printf("web %d:", i); 55 for (j = 0; j < iOP; ++j) printf(" %d", opt[j]); 56 puts(""); 57 } 58 } 59 printf("total: %d\n", total); 60 return 0; 61 }