hdu ----3695 Computer Virus on Planet Pandora (ac自动机)
Computer Virus on Planet Pandora
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 256000/128000 K (Java/Others)
Total Submission(s): 2975 Accepted Submission(s):
833
planet Pandora, hackers make computer virus, so they also have anti-virus software. Of course they learned virus scanning algorithm from the Earth. Every virus has a pattern string which consists of only capital letters. If a virus’s pattern string is a substring of a program, or the pattern string is a substring of the reverse of that program, they can say the program is infected by that virus. Give you a program and a list of virus pattern strings, please write a program to figure out how many viruses the program is infected by.
For each test case:
The first line is a integer n( 0 < n <= 250) indicating the number of virus pattern strings.
Then n lines follows, each represents a virus pattern string. Every pattern string stands for a virus. It’s guaranteed that those n pattern strings are all different so there
are n different viruses. The length of pattern string is no more than 1,000 and a pattern string at least consists of one letter.
The last line of a test case is the program. The program may be described in a compressed format. A compressed program consists of capital letters and
“compressors”. A “compressor” is in the following format:
[qx]
q is a number( 0 < q <= 5,000,000)and x is a capital letter. It means q consecutive letter xs in the original uncompressed program. For example, [6K] means
‘KKKKKK’ in the original program. So, if a compressed program is like:
AB[2D]E[7K]G
It actually is ABDDEKKKKKKKG after decompressed to original format.
The length of the program is at least 1 and at most 5,100,000, no matter in the compressed format or after it is decompressed to original format.
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<queue> 4 #include<iostream> 5 6 using namespace std; 7 8 const int maxn=26; 9 struct Trie{ 10 11 Trie *child[maxn]; 12 Trie * fail ; 13 int tail; 14 15 //函数不占用内存空间 16 void init(){ 17 for(int i=0;i<maxn ;i++ ) 18 child[i]=NULL; 19 fail=NULL; 20 tail=0; 21 } 22 23 }; 24 25 char var[1010] ,stt[5100010]; 26 char stmp[5100010]={‘\0‘}; 27 28 //构建一个Trie树 29 void BuildTrie(char st[] , Trie * root){ 30 31 Trie * cur ; 32 for( int i=0; st[i] ; i++ ){ 33 int ps=st[i]-‘A‘; 34 if(root->child[ps]==NULL){ 35 cur = new Trie; 36 cur->init(); //初始化 37 root->child[ps]=cur; 38 } 39 root = root->child[ps]; 40 } 41 42 root->tail++; 43 } 44 45 //构造失败指正 46 void BuildFail(Trie * root){ 47 queue<Trie *> sav; 48 Trie * tmp,*cur ; 49 sav.push(root); 50 while(!sav.empty()){ 51 tmp = sav.front(); 52 sav.pop(); 53 for( int i=0 ; i<maxn ; i++ ){ 54 if(tmp->child[i]!=NULL){ 55 if(tmp==root) { 56 tmp->child[i]->fail=root; 57 } 58 else{ 59 cur =tmp; 60 while(cur->fail){ 61 if(cur->fail->child[i]!=NULL){ 62 tmp->child[i]->fail = cur->fail->child[i]; 63 break; 64 } 65 cur =cur->fail; 66 } 67 68 if(cur->fail==NULL) 69 tmp->child[i]->fail = root ; 70 71 } 72 sav.push(tmp->child[i]); 73 } 74 } 75 } 76 } 77 78 //查询 79 int Query( char ss[] , Trie *root){ 80 81 Trie * tmp=root ,*cur; 82 int res=0,ps=0; 83 for(int i=0; ss[i] ;i++){ 84 ps = ss[i]-‘A‘; 85 while(tmp->child[ps]==NULL&&tmp!=root){ 86 tmp=tmp->fail; 87 } 88 tmp = tmp->child[ps]; 89 if(tmp==NULL) tmp=root; 90 cur=tmp; 91 while(cur!=root&&cur->tail>0){ 92 res+=cur->tail; 93 cur->tail=0; 94 cur= cur->fail; 95 } 96 } 97 return res ; 98 } 99 100 //对字符串进行必要的伸展 101 int change(char stt[] ,char stmp []){ 102 103 int i,j; 104 for(i=0,j=0; stt[i] ;i++){ 105 if(stt[i]!=‘[‘){ 106 stmp[j++]=stt[i]; 107 }else{ 108 int k=0,lvar=0; 109 while(stt[++i]>=‘0‘&&stt[i]<=‘9‘){ 110 lvar=lvar*10+(stt[i]-‘0‘); 111 } 112 for(k=0;k<lvar;k++){ 113 stmp[j++]=stt[i]; 114 } 115 i++; 116 } 117 } 118 stmp[j]=‘\0‘; 119 return j; 120 } 121 122 //交换字符 123 void swap(char * a,char *b){ 124 if(*a!=*b) *a^=*b^=*a^=*b; 125 } 126 //对字符串进行反序输入 127 128 void Reverse(char * ss,int len){ 129 130 for(int i=0;i<len/2;i++){ 131 swap(ss[i],ss[len-i-1]); 132 } 133 } 134 135 int main(){ 136 137 int tes,nm,res; 138 scanf("%d",&tes); 139 while(tes--){ 140 res=0; 141 Trie * root = new Trie; 142 root->init(); 143 scanf("%d",&nm); 144 while(nm--){ 145 scanf("%s",var); 146 BuildTrie(var,root); 147 } 148 BuildFail(root); 149 scanf("%s",stt); 150 int len= change(stt,stmp); 151 res=Query(stmp,root); 152 Reverse(stmp,len); 153 res+=Query(stmp,root); 154 printf("%d\n",res); 155 } 156 return 0; 157 }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。