HDU 2896 病毒侵袭

来源:互联网 发布:acg和sia知乎 编辑:程序博客网 时间:2024/06/09 20:14

病毒侵袭

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


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
3aaabbbccc2aaabbbcccbbaacc
 

Sample Output
web 1: 1 2 3total: 1
 

Source
2009 Multi-University Training Contest 10 - Host by NIT
 

Recommend
题目大意:

如题。

思路:

反正就是 AC自动机的变形,想办法把他匹配到的串串保存下来。同时保存下来匹配到了几个串串,sort一下输出就行了。这个题一直超内存,后来改成了 把数组换成了  queue ,刚好卡着内存过去。我发现这里的题目都很奇怪啊,每次都是卡着题目的要求过去。很尴尬。
反正我会在一步一步优化我的 AC自动机的小代码,处理了这么多问题,动态建树的自动机正在走向繁荣昌盛,话说不喜欢静态建树。我也不知道为什么。就是不喜欢。

保存结果那里写的不够简洁,我只是单纯的不想开很大的数组而已。。。。

AC代码:

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<queue>#include<algorithm>using namespace std;char str[100005], keyword[205];int ans[5];int countt;struct node{    node *fail;    node *next[130];    int cnt;    int dex;    node()    {        fail = NULL;        cnt = 0;        for(int i = 0; i < 130; ++i)            next[i] = NULL;    }};queue<node *> que;node *root;void insert(char *str) //建立Trie{    int temp, len;    node *p = root;    len = strlen(str);    for(int i = 0; i < len; ++i)    {        temp = str[i] - ' ';        if(p->next[temp] == NULL)            p->next[temp] = new node();        p=p->next[temp];    }    p->cnt=1;    p->dex=countt;}void build_ac(){    que.push(root);    while(!que.empty())    {        node *p = que.front();        que.pop();        node *temp = NULL;        for(int i = 0; i < 130; ++i)        {            if(p->next[i] != NULL)            {                if(p == root)                    p->next[i]->fail = root;                else                {                    temp = p->fail;                    while(temp != NULL)                    {                        if(temp->next[i] != NULL)                        {                            p->next[i]->fail = temp->next[i];                            break;                        }                        temp = temp->fail;                    }                    if(temp == NULL)                        p->next[i]->fail = root;                }                que.push(p->next[i]);            }        }    }}int query(){    int index, len, result;    int nownum=0;    node *p = root;    result = 0;    len = strlen(str);    for(int i = 0; i < len; ++i)    {        index = str[i] - ' ';        while(p->next[index] == NULL && p != root)        {            p = p->fail;        }        p = p->next[index];        if(p == NULL)            p = root;        node *temp = p;        while(temp != root)        {            if(temp->cnt)            {                ans[nownum]=temp->dex;                nownum++;            }            temp=temp->fail;        }    }    return nownum;}void Delete(node *rt){    if(rt == NULL) return;    for(int i = 0; i < 26; i++)        if(rt->next[i] != NULL) Delete(rt->next[i]);    delete(rt);    rt = NULL;}int main(){    int ncase, num;    while(~scanf("%d",&num))    {        int allans=0;        root = new node();        memset(ans,0,sizeof(ans));        getchar();        countt=1;        for(int i = 0; i < num; ++i)        {            gets(keyword);            insert(keyword);            countt++;        }        build_ac();        int nn;        scanf("%d",&nn);        for(countt=0; countt<nn; countt++)        {            memset(ans,-1,sizeof(ans));            scanf("%s", str);            int haha=query();            if(ans[0]!=-1)            {                sort(ans,ans+haha);                allans++;                int tt=0;                for(int i=0;i<5;i++)                {                    if(ans[i]!=-1)                        tt++;                }                printf("web %d:",countt+1);                for(int i=0;i<tt;i++)                {                    printf(" %d",ans[i]);                }                printf("\n");            }        }        printf("total: %d\n",allans);        Delete(root);    }    return 0;}


0 0
原创粉丝点击