hdu 2896 病毒侵襲

病毒侵襲

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10592    Accepted Submission(s): 2745


Problem Description
當太陽的光輝逐漸被月亮遮蔽,世界失去了光明,大地迎來最黑暗的時刻。。。。在這樣的時刻,人們卻異常興奮——我們能在有生之年看到500年一遇的世界奇觀,那是多麼幸福的事兒啊~~
但網路上總有那麼些網站,開始藉着民衆的好奇心,打着介紹日食的旗號,大肆傳播病毒。小t不幸成爲受害者之一。小t如此生氣,他決定要把世界上所有帶病毒的網站都找出來。當然,誰都知道這是不可能的。小t卻執意要完成這不能的任務,他說:“子子孫孫無窮匱也!”(愚公後繼有人了)。
萬事開頭難,小t收集了好多病毒的特徵碼,又收集了一批詭異網站的源碼,他想知道這些網站中哪些是有病毒的,又是帶了怎樣的病毒呢?順便還想知道他到底收集了多少帶病毒的網站。這時候他卻不知道何從下手了。所以想請大家幫幫忙。小t又是個急性子哦,所以解決問題越快越好哦~~
 

Input
第一行,一個整數N(1<=N<=500),表示病毒特徵碼的個數。
接下來N行,每行表示一個病毒特徵碼,特徵碼字符串長度在20—200之間。
每個病毒都有一個編號,依此爲1—N。
不同編號的病毒特徵碼不會相同。
在這之後一行,有一個整數M(1<=M<=1000),表示網站數。
接下來M行,每行表示一個網站源碼,源碼字符串長度在7000—10000之間。
每個網站都有一個編號,依此爲1—M。
以上字符串中字符都是ASCII碼可見字符(不包括回車)。
 

Output
依次按如下格式輸出按網站編號從小到大輸出,帶病毒的網站編號和包含病毒編號,每行一個含毒網站信息。
web 網站編號: 病毒編號 病毒編號 …
冒號後有一個空格,病毒編號按從小到大排列,兩個病毒編號之間用一個空格隔開,如果一個網站包含病毒,病毒數不會超過3個。
最後一行輸出統計信息,如下格式
total: 帶病毒網站數
冒號後有一個空格。
 

Sample Input
3 aaa bbb ccc 2 aaabbbccc bbaacc
 

Sample Output
web 1: 1 2 3 total: 1
 

Source
 

題意:
N(N <= 500)個長度不大於200的模式串(保證所有的模式串都不相同)M(M <= 1000)個長度不大於10000的待匹配串,問待匹配串中有
哪幾個模式串,題目保證每個待匹配串中最多有三個模式串。

題解:這題是一道比較簡單的自動機,但是要注意幾點:一是字符種類的範圍建議採用是0~127,然後減去的是‘\0’,
當然,也可以開0~96,但減去的就應該是‘ ’(空格符),因爲前31個字符鍵盤上是打不出來的,(剛開始就是沒想清楚這個,
然後各種RE),另外就是它輸出是要求排序的
代碼:
  1. #include<cmath>  
  2. #include<cstdio>  
  3. #include<cstring>  
  4. #include<iostream>  
  5. #include<algorithm>  
  6. #define kind 127  
  7. using namespace std;  
  8.   
  9. struct node{  
  10.     node *fail;  
  11.     node *next[kind];  
  12.     int coun;  
  13.     node()  
  14.     {  
  15.         fail = NULL;  
  16.         coun = 0;  
  17.         memset(next,NULL,sizeof(next)); 
  18.         //cout<<sizeof(next)<<endl;  
  19.     }  
  20. }*q[100010];  
  21. int xx[23];  
  22. struct num{  
  23.     int number[5];  
  24.     int many;  
  25. }ans[10005];  
  26.   
  27. char key[205];  
  28. char str[10010];  
  29. void AC_insert(int num,node *root)  //trie圖構造
  30. {  
  31.     node *p = root;  
  32.     int i = 0,index;  
  33.     while(key[i])  
  34.     {  
  35.         index = key[i]-'\0';
  36.         if(p->next[index]==NULL)  
  37.             p->next[index] = new node();  
  38.         p = p->next[index];  
  39.         i++;  
  40.     }  
  41.     p->coun = num;  //標記是哪種病毒
  42. }  
  43.   
  44. void build_AC_fail(node *root)  //失敗指針的構造
  45. {  
  46.     int i,head=0,tail=0;  
  47.     root->fail=NULL;  
  48.     q[tail++] = root;  
  49.     while(head!=tail)  
  50.     {  
  51.         node *temp = q[head++];  
  52.         node *p = NULL;  
  53.         for(i=0;i<127;i++)  
  54.         {  
  55.             if(temp->next[i]!=NULL)  
  56.             {  
  57.                 if(temp == root)  
  58.                     temp->next[i]->fail = root;  
  59.                 else {  
  60.                     p = temp->fail;  
  61.                     while(p!=NULL)  
  62.                     {  
  63.                         if(p->next[i]!=NULL)  
  64.                         {  
  65.                             temp->next[i]->fail = p->next[i];  
  66.                             break;  
  67.                         }  
  68.                         p = p->fail;  
  69.                     }  
  70.                     if(p==NULL) temp->next[i]->fail = root;  
  71.                 }  
  72.                 q[tail++] = temp->next[i];  
  73.             }  
  74.         }  
  75.     }  
  76. }  
  77.   
  78. void query(int cas,node *root)  
  79. {  
  80.     int i =0,m = 0,index;  
  81.     node *p = root;  
  82.     while(str[i])  
  83.     {  
  84.         index = str[i]-'\0';  
  85.         while(p->next[index] == NULL && p!=root)  
  86.             p = p->fail;  
  87.         p = p->next[index];  
  88.         if(p==NULL)  
  89.             p = root;  
  90.         node *temp = p;  
  91.         while(temp!=root&&temp->coun!=-1)  
  92.         {  
  93.             if(temp->coun!=0)  
  94.                 ans[cas].number[m++] = temp->coun;  
  95.             temp = temp->fail;  
  96.         }  
  97.         i++;  
  98.     }  
  99.     ans[cas].many = m;  
  100. }  
  101.   
  102. int deal_ac_automation(node* T)//釋放空間  
  103. {  
  104.     int i;  
  105.     if(T==NULL)  
  106.         return 0;  
  107.     for(i=0;i<127;i++)  
  108.     {  
  109.         if(T->next[i]!=NULL)  
  110.             deal_ac_automation(T->next[i]);  
  111.     }  
  112.     free(T);  
  113.     return 0;  
  114. }  
  115.   
  116. int main()  
  117. {  
  118.     int n,m,i,j,toal;  
  119.     while(~scanf("%d",&n))  
  120.     {  
  121.         toal = 0;  
  122.         node *root = new node();  
  123.         getchar();  
  124.         for(i=1;i<=n;i++)  
  125.         {  
  126.             gets(key);  
  127.             AC_insert(i,root);  
  128.         }  
  129.         build_AC_fail(root);  
  130.         scanf("%d",&m);  
  131.         for(i=1;i<=m;i++)  
  132.         {  
  133.             scanf("%s",str);  
  134.             query(i,root);  
  135.         }  
  136.         for(i=1;i<=m;i++)  
  137.         {  
  138.             if(ans[i].many)  
  139.             {  
  140.                 toal ++;  
  141.                 printf("web %d:",i);  
  142.                 sort(ans[i].number,ans[i].number+ans[i].many);  
  143.                 for(j = 0;j<ans[i].many;j++)  
  144.                     printf(" %d",ans[i].number[j]);  
  145.                 cout<<endl;  
  146.             }  
  147.         }  
  148.         printf("total: %d\n",toal);  
  149.         //deal_ac_automation(root);  
  150.     }  
  151.     return 0;  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章