HDU-3065(病毒侵袭持续中)
题意不用多说,此题AC自动机模板题,考虑读者已经掌握了AC自动机,可以切这个题来巩固一下,
最坑的地方是多case题目居然没有说~!!!一直wa的同学们看看自己是不是用了多case。
题目原址:http://acm.hdu.edu.cn/showproblem.php?pid=3065
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //==================================================================== 2 //Name : 3 //Author :hxf 4 //copyright :http://www.cnblogs.com/Free-rein/ 5 //Description: 6 //Data :2012.8.8 7 //======================================================================== 8 #include<iostream> 9 #include<algorithm> 10 #include<stdio.h> 11 #include<math.h> 12 #include<string.h> 13 #include<vector> 14 #include<stack> 15 #include<queue> 16 #define MAX 100005 17 #define inf 1499999999 18 using namespace std; 19 const int len=28;//最多只有26个英文字母 20 struct Tril{ 21 Tril *fail; 22 Tril *son[len]; 23 int count; 24 Tril(){ 25 fail=NULL; 26 count=0; 27 memset(son,NULL,sizeof(son)); 28 } 29 }; 30 char str[2000050]; 31 char word[1005][55]; 32 int ans[1005]; 33 void creat(char *word,Tril *root,int num)///////////插入tril树 34 { 35 Tril *p=root; 36 int lenth=strlen(word); 37 for(int i=0;i<lenth;i++) 38 { 39 int index=word[i]-'A'; 40 if(p->son[index]==NULL) 41 p->son[index]=new Tril(); 42 p=p->son[index]; 43 } 44 p->count=num; 45 } 46 void creat_ac_automation(Tril *root)/////寻找失败节点 47 { 48 queue<Tril *> q; 49 root->fail = NULL; 50 q.push(root); 51 while (!q.empty()) { 52 Tril * p_cur = q.front(); 53 q.pop(); 54 for (int i = 0; i < 26; ++i) { 55 if (p_cur->son[i] != NULL) { 56 if (p_cur == root) { 57 p_cur->son[i]->fail = root; 58 } else { 59 Tril * temp = p_cur->fail; 60 while (temp != NULL) { 61 if (temp->son[i] != NULL) { 62 p_cur->son[i]->fail = temp->son[i]; 63 break; 64 } 65 temp = temp->fail; 66 } 67 if (temp == NULL) { 68 p_cur->son[i]->fail = root; 69 } 70 } 71 q.push(p_cur->son[i]); 72 } 73 } 74 } 75 } 76 void query(Tril *root)//从str字符串中查询word单词出现的个数 77 { 78 int lenth=strlen(str); 79 Tril *p=root; 80 for(int i=0;i<lenth;i++) 81 { 82 if(str[i]<'A'||str[i]>'Z') 83 { 84 p=root; 85 continue; 86 } 87 int index=str[i]-'A'; 88 while(p->son[index]==NULL&&p!=root) 89 { 90 p=p->fail; 91 } 92 p=p->son[index]; 93 if(p==NULL) 94 p=root; 95 Tril *k=p; 96 while(k!=root) 97 { 98 if(k->count>0) 99 { 100 int s=k->count; 101 ans[s]++; 102 } 103 k=k->fail; 104 } 105 } 106 } 107 int main() 108 { 109 int n; 110 while(~scanf("%d", &n)) 111 { 112 memset(ans,0,sizeof(ans)); 113 Tril *root=new Tril(); 114 scanf("%d",&n); 115 for(int i=1;i<=n;i++) 116 { 117 scanf("%s",word[i]); 118 getchar(); 119 creat(word[i],root,i); 120 } 121 creat_ac_automation(root); 122 scanf("%s",str); 123 getchar(); 124 query(root); 125 for(int i=1;i<=n;i++) 126 { 127 if(ans[i]>0) 128 { 129 printf("%s: %d\n",word[i],ans[i]); 130 } 131 } 132 } 133 return 0; 134 }