首页 > 学院 > 开发设计 > 正文

hdu2896 病毒侵袭

2019-11-09 20:22:24
字体:
来源:转载
供稿:网友

hdu 2896

Description

当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻。。。。在这样的时刻,人们却异常兴奋——我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事儿啊~~但网路上总有那么些网站,开始借着民众的好奇心,打着介绍日食的旗号,大肆传播病毒。小t不幸成为受害者之一。小t如此生气,他决定要把世界上所有带病毒的网站都找出来。当然,谁都知道这是不可能的。小t却执意要完成这不能的任务,他说:“子子孙孙无穷匮也!”(愚公后继有人了)。万事开头难,小t收集了好多病毒的特征码,又收集了一批诡异网站的源码,他想知道这些网站中哪些是有病毒的,又是带了怎样的病毒呢?顺便还想知道他到底收集了多少带病毒的网站。这时候他却不知道何从下手了。所以想请大家帮帮忙。小t又是个急性子哦,所以解决问题越快越好哦~~

Input

第一行,一个整数N(1<=N<=500),表示病毒特征码的个数。 接下来N行,每行表示一个病毒特征码,特征码字符串长度在20—200之间。 每个病毒都有一个编号,依此为1—N。 不同编号的病毒特征码不会相同。 在这之后一行,有一个整数M(1<=M<=1000),表示网站数。 接下来M行,每行表示一个网站源码,源码字符串长度在7000—10000之间。 每个网站都有一个编号,依此为1—M。 以上字符串中字符都是ASCII码可见字符(不包括回车)。

Output

依次按如下格式输出按网站编号从小到大输出,带病毒的网站编号和包含病毒编号,每行一个含毒网站信息。 web 网站编号: 病毒编号 病毒编号 … 冒号后有一个空格,病毒编号按从小到大排列,两个病毒编号之间用一个空格隔开,如果一个网站包含病毒,病毒数不会超过3个。 最后一行输出统计信息,如下格式 total: 带病毒网站数 冒号后有一个空格。

Sample Input

3 aaa bbb ccc 2 aaabbbccc bbaacc

Sample Output

web 1: 1 2 3 total: 1

题解

裸题,直接AC自动机即可。

#include<cstdio>#include<iostream>#include<cstring>#include<queue>using namespace std;const int max_size = 200*501, ch_size = 130, M = 10000 + 10, N = 500 + 10;char s[M];int n, m;int sum;struct Trie{ int c[max_size][ch_size]; int val[max_size], f[max_size], last[max_size]; int sz; int ans[N]; bool ok; Trie() {sz = 1;} int idx(char c) {return (int)c;} void insert(char *s, int v){ int u = 0, n = strlen(s); for(int i = 0; i < n; i++){ int x = idx(s[i]); if(!c[u][x]){ c[u][x] = sz++; val[sz] = 0; } u = c[u][x]; } val[u] = v; } void get_fail(){ queue<int> q; f[0] = 0; for(int i = 0; i < ch_size; i++){ int u = c[0][i]; if(u){ f[u] = 0; q.push(u); last[u] = 0; } } while(!q.empty()){ int r = q.front(); q.pop(); for(int i = 0; i < ch_size; i++){ int u = c[r][i]; if(!u) {c[r][i] = c[f[r]][i]; continue;} q.push(u); int v = f[r]; while(v && !c[v][i]) v = f[v]; f[u] = c[v][i]; last[u] = val[f[u]] ? f[u] : last[f[u]]; } } } void PRint(int j){ ok = 1; //printf("%d %d/n", j, val[j]); if(j){ ans[val[j]] = 1; print(last[j]); } } void match(char *s){ int len = strlen(s), j = 0; for(int i = 0; i < len; i++){ int ch = idx(s[i]); j = c[j][ch]; if(val[j]) print(j); else if(val[last[j]]) print(last[j]); } }}t;void init(){ scanf("%d", &n); for(int i = 1; i <= n; i++){ scanf("%s", s); t.insert(s, i); } t.get_fail();}void work(){ scanf("%d", &m); for(int i = 1; i <= m; i++){ scanf("%s", s); memset(t.ans, 0, sizeof(t.ans)); t.ok = 0; t.match(s); if(t.ok){ sum++; printf("web %d:", i); for(int j = 1; j <= n; j++) if(t.ans[j]) printf(" %d", j); puts(""); } } printf("total: %d/n", sum);}int main(){ freopen("virus.in", "r", stdin); freopen("virus.out", "w", stdout); init(); work(); return 0;}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表