题目大意:给一些病毒字符串,问一些网址中有哪些病毒。
思路:AC自动机挺裸的题,但是听说Trie图还好写,时间还快,以后就不写AC自动机了,直接啥题都上Trie图吧。
注意:此题输出结尾要加回车,否则会PE!
CODE:
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; struct Trie{ Trie *son[130],*fail; int id; Trie() { id = 0; memset(son,NULL,sizeof(son)); } }*root = new Trie(); int cnt,asks; char s[10010]; bool v[1010]; int ill[1010]; inline void Insert(char *s,int p) { Trie *now = root; while(*s != '\0') { if(now->son[*s] == NULL) now->son[*s] = new Trie(); now = now->son[*s]; ++s; } now->id = p; } void MakeTrieGraph() { static queue<Trie *> q; while(!q.empty()) q.pop(); for(int i = 0; i < 128; ++i) if(root->son[i] != NULL) root->son[i]->fail = root,q.push(root->son[i]); while(!q.empty()) { Trie *now = q.front(); q.pop(); for(int i = 0; i < 128; ++i) if(now->son[i] != NULL) { Trie *temp = now->fail; while(temp != root && temp->son[i] == NULL) temp = temp->fail; if(temp->son[i] != NULL) temp = temp->son[i]; now->son[i]->fail = temp; q.push(now->son[i]); } else now->son[i] = now->fail->son[i] ? now->fail->son[i]:root; } } inline void Ask(char *s) { Trie *now = root; while(*s != '\0') { if(now->son[*s] != NULL) now = now->son[*s]; for(Trie *temp = now; temp != root; temp = temp->fail) if(temp->id && !v[temp->id]) v[temp->id] = true,ill[++ill[0]] = temp->id; ++s; } } int main() { cin >> cnt; for(int i = 1; i <= cnt; ++i) { scanf("%s",s); Insert(s,i); } MakeTrieGraph(); cin >> asks; int ans = 0; for(int i = 1; i <= asks; ++i) { memset(v,false,sizeof(v)); memset(ill,0,sizeof(ill)); scanf("%s",s); Ask(s); if(ill[0]) { ++ans; sort(ill + 1,ill + ill[0] + 1); printf("web %d:",i); for(int j = 1; j <= ill[0]; ++j) printf(" %d",ill[j]); puts(""); } } printf("total: %d\n",ans); return 0; }
原文地址:http://blog.csdn.net/jiangyuze831/article/details/41542741