[HDU 2896] virus attack [AC automaton] [virus signature match]

Source: Internet
Author: User
Tags control characters

Virus attack Time limit:2000/1000 MS (java/others) Memory limit:32768/32768 K (java/others)
Total submission (s): 20728 Accepted Submission (s): 5058


Problem description When the sun's glow is gradually obscured by the moon, the world loses its light, the Earth ushered in the darkest moment .... At such times, people are very excited-we can live to see 500 years of the world's wonders, that is how happy things ah ~ ~
But there are always some websites on the internet, beginning with the curiosity of the people, introducing the banner of the solar eclipse, spreading the virus in a big way. Little T unfortunately became one of the victims. Little T was so angry that he decided to find all the virus-infected websites in the world. Of course, everyone knows it's impossible. Small T but insisted to complete this cannot task, he said: "Descendants infinite chamber also!" "(The Foolish Gong successors).
Everything at the beginning of the difficult, small t collected a lot of virus signatures, but also collected a number of strange web site source, he would like to know which of these sites are virus, and what kind of virus? By the way, I wonder how many websites he collects with viruses. At this time he did not know where to start. So I would like to ask you to help. Small T is also a short-tempered oh, so the faster the better to solve the problem Oh ~ ~

Input first line, an integer N (1<=n<=500) that represents the number of virus signatures.
Next n rows, each line represents a virus signature, and the signature string length is between 20-200.
Each virus has a number, according to 1-n.
Virus signatures of different numbers will not be the same.
After this line, there is an integer M (1<=m<=1000) that represents the number of sites.
Next m line, each line represents a website source code, the source string length between 7000-10000.
Each site has a number, depending on the 1-m.
The characters in the above string are ASCII visible characters (not including carriage returns).

Output is exported sequentially by site number from small to large output, with the virus's website number and with the virus number, each line of a poison site information.
Web site number: Virus ID virus number ...
There is a space after the colon, the virus number is arranged from small to large, two virus numbers separated by a space, if a website contains a virus, the number of viruses will not exceed 3.
The last line of output statistics, the following format
Total: Number of sites with viruses
There is a space after the colon.

Sample Input
3aaabbbccc2aaabbbcccbbaacc

Sample Output
Web 1:1 2 3total:1

Source2009 multi-university Training Contest 10-host by NIT
Recommendgaojie | We have carefully selected several similar problems for you:3065 2243 2825 3341 3247


Come on, the title is finished, first spit groove. Why does the question hang in space?

/*author:lucifinil.date:2016-7-23.description:ac automata algorithm solves the problem of multi-pattern matching. PROBLEM_ID:HDU 2896 */#include <cstdio># Include<cstring> #include <queue>using namespace std;//declaration Trie Dictionary Tree Class int n;struct trie{#define SIGMA_SIZE 128/ /sigma_size, Character set size public://constructor [common] Initialize Trie () {cnt = 0; Fail = null;for (int i=0;i<sigma_size;i++) next[i]=null; }trie* fail;//fail pointer trie* next[sigma_size];//next[] pointer int cnt;//number};//optimize space//#define Max_len 210//char tmp[max_len];// Temporary storage Signature//insert (), inserting a signature into the dictionary tree Trie void Insert (char* str,trie* root,int ID) {//Because the pointer is degraded, so *str points to the first element in tmp[]// We only need to str++, we can traverse the tmp[]//string to ' s ' End condition for false end loop while (*STR) {///in ASCII code 0~31 and 127 (total 33) are control characters or communication-specific characters. so int index = *STR-31 ;//Calculate subscript if (root->next[index]==null) Root->next[index] = new class Trie;root = root->next[index];// Because of the scope, the root pointer here is not a global pointer to the trie root node str++;} root->cnt = id;//Record This is the signature of the first few viruses}/*getfail (trie* root) Description: Computes the Fail pointer (mismatch pointer) for easy solution using AC automata. The queued queue is used for BFS traversal when calculating. */queue<trie*> q;void GETFAIl (trie* root) {Root->fail = Null;q.push (Root), while (!q.empty ()) {trie* p = q.front (), Q.pop (); for (int i=0;i<sigma _size;i++) {if (p->next[i]!=null) {/* Two processing if P is root (the root of the trie tree does not represent any characters) So the fail pointer of the currently traversed node is pointing to root. Otherwise, traverse the mismatch pointer of P. The fail pointer of the son node of P points to the son of the node to which the P mismatch pointer points. */if (p==root) p->next[i]->fail = root;else{trie* ptr = P->fail;while (p!=null) {if (ptr->next[i]!=null) p >next[i]->fail = ptr->next[i];break; }if (Ptr==null)//traverse a lap not found, then point to root. (restart) {p->next[i]->fail = root;}} Q.push (P->next[i]);}}} int m; #define MAX_LEN2 10010char pat[max_len2];//website Source length #define MAXN 501bool mark[maxn];/*int query (trie* root,char* Pat) Description: Matches str. */int query (trie* root,char* str) {trie* p = root;int tot = 0;//number of successful matches [return value] while (*STR) {int index = *str-31;//calculate subscript while (P->next[index]==null&&p!=root) p=p->fail;//mismatch along the mismatch pointer//is currently not the root of the contract, because the root mismatch can not match. p = P-&GT;NEXT[INDEX];//2 Case cannot match or find match point if (p==null) p=root;//restart trie* ptr = p;while (ptr!=root&&ptr->cnt!= 0) {//Match successful one if (!mark[ptr->cnt]) {tot++;mark[ptr->cnt] = 1;} ptr = ptr--Fail;} str++;} return tot;} int main () {while (scanf ("%d", &n)!=eof) {trie* root = new Class trie;//creates a root node GetChar ();//Read carriage return for (int i=1;i<=n;i++) { scanf ("%s", Pat); Insert (pat,root,i);} Getfail (root);//Gets the fail pointer in the current trie tree [AC Automaton]scanf ("%d", &m); int tot = 0; for (int i=1;i<=m;i++) {memset (mark,0,sizeof (Mark)), scanf ("%s", Pat), int flag = query (ROOT,PAT);//Start matching if (flag)// The match succeeds {printf ("Web%d:", I), for (int j=1;j<=n;j++) if (Mark[j]) printf ("%d", j);p UTS ("");//output line break tot++;}} printf ("Total:%d\n", tot);} return 0;}
Why this graceful code would be MLE or RE (burst space during the run).

However...

</pre><pre style= "Color:rgb (0, 0, 0); Font-style:normal; Font-variant:normal; Font-weight:normal; Letter-spacing:normal; Line-height:normal; Orphans:auto; Text-align:start; text-indent:0px; Text-transform:none; widows:1; word-spacing:0px; -webkit-text-stroke-width:0px; " >/*author:lucifinil.date:2016-7-23.description:ac automata algorithm solves the problem of multi-pattern matching. PROBLEM_ID:HDU 2896 */#include <cstdio># include<iostream> #include <cmath> #include <cstring> #include <algorithm> #include <queue >using namespace std;//declaration Trie Dictionary Tree Class int n;struct Trie{trie *next[95]; Trie *fail;int CNT; Trie () {fail=null;cnt=0;for (int i=0;i<95;i++) {next[i]=null;}}} *E[100005]; #define Max_len 210char tmp[max_len];//temporary storage signature//insert (), insert the signature into the dictionary tree Trie void Insert (char* str,trie* Root,int ID) {//Because the pointer is degraded, so *str points to the first element in tmp[]//We only need to str++, we can traverse the tmp[]//string to '% ' end condition for false end loop while (*STR) {//in ASCII code 0~ 31 and 127 (a total of 33) are control characters or communication-specific characters. so int index = *str-31;//calculates the subscript if (root->next[index]==null) root->nExt[index] = new class Trie;root = root->next[index];//because of scope the root pointer here is not a global pointer to the Trie root node str++;} root->cnt = id;//Record This is the signature of the first few viruses}/*getfail (trie* root) Description: Computes the Fail pointer (mismatch pointer) for easy solution using AC automata. The queued queue is used for BFS traversal when calculating. */queue<trie*> q;void getfail (trie* root) {int Tou=0,tail=1;e[0]=root;root->fail=null;while (tou<tail) { Trie *p=e[tou++];       Trie *temp=null;    for (int i=0;i<95;i++) {if (P->next[i]) {if (p==root) p->next[i]->fail=root;     else {Trie *pre=p->fail;      while (PRE) {if (Pre->next[i]) {p->next[i]->fail=pre->next[i];      Break     } pre=pre->fail;    } if (!pre) p->next[i]->fail=root;   } e[tail++]=p->next[i]; }}}}int m; #define MAX_LEN2 10010char pat[max_len2];//website Source length #define MAXN 501int mark[maxn];/*int query (trie* root,cha r* Pat) Description: Matches str. */int query (trie* root,char* str) {trie* p = root;int tot = 0;//number of successful matches [return value] while (*STR) {int index = *str-31;//calculates subscript while (P->next[index]==null&&p!=root) p=p->fail;//mismatch along the mismatch pointer//is currently not the root of the contract, because the root mismatch cannot match. p = P-&GT;NEXT[INDEX];//2 Case cannot match or find match point if (p==null) p=root;//restart trie* ptr = p;while (ptr!=root&&ptr->cnt!= 0) {//Match succeeds one if (!mark[ptr->cnt]) {tot++;mark[ptr->cnt] = 1;} ptr = ptr---fail;} str++;} return tot;} int main () {while (scanf ("%d", &n)!=eof) {trie* root = new Class trie;//creates a root node GetChar ();//Read carriage return for (int i=1;i<=n;i++) { scanf ("%s", TMP); Insert (tmp,root,i);} Getfail (root);//Gets the fail pointer in the current trie tree [AC Automaton]scanf ("%d", &m); int tot = 0; for (int i=1;i<=m;i++) {memset (mark,0,sizeof (Mark)), scanf ("%s", Pat), int flag = query (ROOT,PAT);//Start matching if (flag)// The match succeeds {printf ("Web%d:", I), for (int j=1;j<=n;j++) if (Mark[j]) printf ("%d", j);p UTS ("");//output line break tot++;}} printf ("Total:%d\n", tot);} return 0;}

Change the next[] to a small ... What do I have to say about this TM?

Give another copy of the array version code

#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <    queue>using namespace std;struct trie{int next[210*500][128],fail[210*500],end[210*500];    int root,l;        int NewNode () {for (int i = 0;i < 128;i++) Next[l][i] =-1;        end[l++] =-1;    return L-1;        } void Init () {L = 0;    root = NewNode ();        } void Insert (char s[],int ID) {int len = strlen (s);        int now = root;            for (int i = 0;i < len;i++) {if (next[now][s[i]] = =-1) next[now][s[i]] = NewNode ();        Now=next[now][s[i]];    } End[now]=id;        } void Build () {queue<int>q;        Fail[root] = root;            for (int i = 0;i < 128;i++) if (next[root][i] = =-1) next[root][i] = root;                else {Fail[next[root][i]] = root;       Q.push (Next[root][i]);     } while (!            Q.empty ()) {int now = Q.front ();            Q.pop ();                for (int i = 0;i < 128;i++) if (next[now][i] = =-1) next[now][i] = Next[fail[now]][i];                    else {Fail[next[now][i]] = next[fail[now]][i];                Q.push (Next[now][i]);    }}} bool used[510];        BOOL Query (char buf[],int n,int ID) {int len = strlen (BUF);        int now = root;        memset (used,false,sizeof (used));        BOOL flag = FALSE;            for (int i = 0;i < len;i++) {now = Next[now][buf[i]];            int temp = now; while (temp! = root) {if (end[temp]! =-1) {used[end[temp]] =                    True                Flag = true;            } temp = fail[temp];        }} if (!flag) return false;        printf ("Web%d:", id); Forint i = 1;i <= n;i++) if (Used[i]) printf ("%d", I);        printf ("\ n");    return true; }};char buf[10010];    Trie Ac;int Main () {int n,m;        while (scanf ("%d", &n)! = EOF) {ac.init ();            for (int i = 1;i <= n;i++) {scanf ("%s", buf);        Ac.insert (Buf,i);        } ac.build ();        int ans = 0;        scanf ("%d", &m);            for (int i = 1;i <= m;i++) {scanf ("%s", buf);        if (Ac.query (buf,n,i)) ans++;    } printf ("Total:%d\n", ans); } return 0;}


[HDU 2896] virus attack [AC automaton] [virus signature match]

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.