hdu2896 病毒侵袭 ac自动机
生活随笔
收集整理的這篇文章主要介紹了
hdu2896 病毒侵袭 ac自动机
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=2896
題目:
病毒侵襲
Time Limit: 2000/1000 MS (Java/Others)????Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 23013????Accepted Submission(s): 5551
但網(wǎng)路上總有那么些網(wǎng)站,開始借著民眾的好奇心,打著介紹日食的旗號,大肆傳播病毒。小t不幸成為受害者之一。小t如此生氣,他決定要把世界上所有帶病毒的網(wǎng)站都找出來。當然,誰都知道這是不可能的。小t卻執(zhí)意要完成這不能的任務(wù),他說:“子子孫孫無窮匱也!”(愚公后繼有人了)。
萬事開頭難,小t收集了好多病毒的特征碼,又收集了一批詭異網(wǎng)站的源碼,他想知道這些網(wǎng)站中哪些是有病毒的,又是帶了怎樣的病毒呢?順便還想知道他到底收集了多少帶病毒的網(wǎng)站。這時候他卻不知道何從下手了。所以想請大家?guī)蛶兔ΑP又是個急性子哦,所以解決問題越快越好哦~~
?
Input 第一行,一個整數(shù)N(1<=N<=500),表示病毒特征碼的個數(shù)。接下來N行,每行表示一個病毒特征碼,特征碼字符串長度在20—200之間。
每個病毒都有一個編號,依此為1—N。
不同編號的病毒特征碼不會相同。
在這之后一行,有一個整數(shù)M(1<=M<=1000),表示網(wǎng)站數(shù)。
接下來M行,每行表示一個網(wǎng)站源碼,源碼字符串長度在7000—10000之間。
每個網(wǎng)站都有一個編號,依此為1—M。
以上字符串中字符都是ASCII碼可見字符(不包括回車)。
?
Output 依次按如下格式輸出按網(wǎng)站編號從小到大輸出,帶病毒的網(wǎng)站編號和包含病毒編號,每行一個含毒網(wǎng)站信息。web 網(wǎng)站編號: 病毒編號 病毒編號 …
冒號后有一個空格,病毒編號按從小到大排列,兩個病毒編號之間用一個空格隔開,如果一個網(wǎng)站包含病毒,病毒數(shù)不會超過3個。
最后一行輸出統(tǒng)計信息,如下格式
total: 帶病毒網(wǎng)站數(shù)
冒號后有一個空格。
?
Sample Input 3 aaa bbb ccc 2 aaabbbccc bbaacc?
Sample Output web 1: 1 2 3 total: 1 思路:自動機模板題,不過內(nèi)存卡的蛋疼。。。 一開始mle,然后我把數(shù)組改成short,結(jié)果瘋狂re,,還一直找不到原因,,,折騰了一個多小時,后來無意之下改成了int后(調(diào)整了數(shù)組大小)居然ac了,此刻我的內(nèi)心是崩潰的== 原來short這么小,哭瞎 代碼:?
1 #include <queue> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 struct AC_auto 6 { 7 const static int LetterSize = 128; 8 const static int TrieSize = 128 * 510; 9 10 int tot,root,fail[TrieSize],end[TrieSize],next[TrieSize][LetterSize]; 11 12 int newnode(void) 13 { 14 memset(next[tot],-1,sizeof(next[tot])); 15 end[tot] = 0; 16 return tot++; 17 } 18 19 void init(void) 20 { 21 tot = 0; 22 root = newnode(); 23 } 24 25 int getidx(char x) 26 { 27 return (int)x; 28 } 29 30 void insert(char *ss,int x) 31 { 32 int len = strlen(ss); 33 int now = root; 34 for(int i = 0; i < len; i++) 35 { 36 int idx = getidx(ss[i]); 37 if(next[now][idx] == -1) 38 next[now][idx] = newnode(); 39 now = next[now][idx]; 40 } 41 end[now]=x; 42 } 43 44 void build(void) 45 { 46 queue<int>Q; 47 fail[root] = root; 48 for(int i = 0; i < LetterSize; i++) 49 if(next[root][i] == -1) 50 next[root][i] = root; 51 else 52 fail[next[root][i]] = root,Q.push(next[root][i]); 53 while(Q.size()) 54 { 55 int now = Q.front();Q.pop(); 56 for(int i = 0; i < LetterSize; i++) 57 if(next[now][i] == -1) next[now][i] = next[fail[now]][i]; 58 else 59 fail[next[now][i]] = next[fail[now]][i],Q.push(next[now][i]); 60 } 61 } 62 63 int match(char *ss,int n,int x) 64 { 65 int len,now,use[501],ff; 66 memset(use,0,sizeof use); 67 len = strlen(ss),now = root,ff=0; 68 for(int i = 0; i < len; i++) 69 { 70 int idx = getidx(ss[i]); 71 int tmp = now = next[now][idx]; 72 while(tmp) 73 { 74 if(end[tmp]) 75 use[end[tmp]]=1,ff=1; 76 tmp = fail[tmp]; 77 } 78 } 79 if(!ff)return 0; 80 printf("web %d:",x); 81 for(int j=1; j<=n; j++)if(use[j]) 82 printf(" %d",j); 83 printf("\n"); 84 return 1; 85 } 86 87 }; 88 89 AC_auto ac; 90 char ss[10011]; 91 int main(void) 92 { 93 int n,m,ans=0; 94 scanf("%d",&n); 95 ac.init(); 96 for(int i=1; i<=n; i++) 97 scanf("%s",ss),ac.insert(ss,i); 98 scanf("%d",&m); 99 ac.build(); 100 for(int i=1; i<=m; i++) 101 { 102 scanf("%s",ss); 103 if(ac.match(ss,n,i)) 104 ans++; 105 } 106 printf("total: %d\n",ans); 107 return 0; 108 }?
轉(zhuǎn)載于:https://www.cnblogs.com/weeping/p/5937122.html
總結(jié)
以上是生活随笔為你收集整理的hdu2896 病毒侵袭 ac自动机的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 集群(cluster)原理(转)
- 下一篇: 配置虚拟机网桥模式