标签:
题目:给你一些病毒的特征串,再给你一些网站的代码,统计每个网站中出现的病毒和被攻击的网站数。
分析:字符串,AC自动机。数据规模较大,使用 AC自动机。具体参照本站的:AC自动机总结。
说明:开始时把求解 fial合并到 query中了,导致多次 TLE,。。。囧。。。
#include <stdio.h> #include <stdlib.h> #include <string.h> int cmp(const void* a, const void* b) { return *((int *)a) - *((int *)b); } /* AC_DFA define */ #define nodesize 60006 #define dictsize 128 typedef struct node1 { int flag; node1* fail; node1* next[dictsize]; }tnode; tnode dict[nodesize]; tnode* Q[nodesize]; int ID[dictsize]; int answer[10001]; class AC_DFA { private: int size; tnode* root; public: AC_DFA() {makeID();init();} void makeID() { for (int i = 0 ; i < dictsize ; ++ i) ID[i] = i; } void init() { memset(dict, 0, sizeof(dict)); root=NULL;size=0;root=newnode(); } tnode* newnode() { dict[size].fail = root; return &dict[size ++]; } void insert(char* word, int id) { tnode* now = root; for (int i = 0 ; word[i] ; ++ i) { if (!now->next[ID[word[i]]]) now->next[ID[word[i]]] = newnode(); now = now->next[ID[word[i]]]; }now->flag = id; } void setfail() { Q[0] = root; root->fail = NULL; for (int move = 0,save = 1 ; move < save ; ++ move) { tnode* now = Q[move]; for (int i = 0 ; i < 128 ; ++ i) if (now->next[i]) { tnode* p = now->fail; while (p && !p->next[i]) p = p->fail; now->next[i]->fail = p?p->next[i]:root; Q[save ++] = now->next[i]; }else now->next[i] = now==root?root:now->fail->next[i];//构建 Trie图 } } int query(char* line, int id) { int count = 0; tnode* now = root; for (int i = 0 ; line[i] ; ++ i) { now = now->next[ID[line[i]]]; for (tnode* p = now ; p ; p = p->fail) if (p->flag) answer[count ++] = p->flag; } if (count) { qsort(answer, count, sizeof(int), cmp); printf("web %d: %d",id,answer[0]); for (int i = 1 ; i < count ; ++ i) if (answer[i] != answer[i-1]) printf(" %d",answer[i]); printf("\n"); } return count > 0; } }; /* AC_DFA end */ char Word[205]; char Line[10005]; int main() { int T,N,M,Sum; AC_DFA ac; scanf("%d",&N); for (int i = 1 ; i <= N ; ++ i) { scanf("%s",Word); ac.insert(Word, i); } ac.setfail(); scanf("%d",&M); Sum = 0; for (int i = 1 ; i <= M ; ++ i ) { scanf("%s",&Line); Sum += ac.query(Line, i); } printf("total: %d\n",Sum); system("pause"); return 0; }
标签:
原文地址:http://blog.csdn.net/mobius_strip/article/details/42099641