hdoj 3065 病毒侵袭持续中 【AC自动机 基础题】【输出每个模式串出现的次数】

来源:互联网 发布:linux mysql 3306端口 编辑:程序博客网 时间:2024/05/20 06:37

病毒侵袭持续中

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


Problem Description
小t非常感谢大家帮忙解决了他的上一个问题。然而病毒侵袭持续中。在小t的不懈努力下,他发现了网路中的“万恶之源”。这是一个庞大的病毒网站,他有着好多好多的病毒,但是这个网站包含的病毒很奇怪,这些病毒的特征码很短,而且只包含“英文大写字符”。当然小t好想好想为民除害,但是小t从来不打没有准备的战争。知己知彼,百战不殆,小t首先要做的是知道这个病毒网站特征:包含多少不同的病毒,每种病毒出现了多少次。大家能再帮帮他吗?
 

Input
第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。
接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。
在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。
 

Output
按以下格式每行一个,输出每个病毒出现次数。未出现的病毒不需要输出。
病毒特征码: 出现次数
冒号后有一个空格,按病毒特征码的输入顺序进行输出。
 

Sample Input
3AABBCCooxxCC%dAAAoen....END
 

Sample Output
AA: 2CC: 1
Hint
Hit:题目描述中没有被提及的所有情况都应该进行考虑。比如两个病毒特征码可能有相互包含或者有重叠的特征码段。计数策略也可一定程度上从Sample中推测。
 


 

思路:直接在查询过程中用一个数组记录当前串的出现次数就ok了。

 

#include <cstdio>#include <cstring>#include <queue>#define MAXN 2000000+10using namespace std;char str[MAXN];char dd[1001][50];int rec[1001];//记录出现次数struct Trie{    int next[50010][130], fail[50010], ID[50010];    int root, L;    int newnode()    {        for(int i = 0; i < 128; i++)            next[L][i] = -1;        ID[L++] = -1;//记录id        return L-1;    }    void init()    {        L = 0;        root = newnode();    }    void Insert(char *buf, int id)    {        int len = strlen(buf);        int now = root;        for(int i = 0; i < len; i++)        {            if(next[now][buf[i]] == -1)                next[now][buf[i]] = newnode();            now = next[now][buf[i]];        }        ID[now] = id;    }    void build()    {        queue<int> Q;        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]);                }            }        }    }    void Query(char *buf)    {        memset(rec, 0, sizeof(rec));//出现次数均为0        int len = strlen(str);        int now = root;        for(int i = 0; i < len; i++)        {            now = next[now][buf[i]];            int temp = now;            while(temp != root)            {                if(ID[temp] != -1)                    rec[ID[temp]]++;                temp = fail[temp];            }        }    }};Trie ac;int main(){    int N;    while(scanf("%d", &N) != EOF)    {        ac.init();        for(int i = 1; i <= N; i++)        {            scanf("%s", dd[i]);            ac.Insert(dd[i], i);        }        ac.build();        scanf("%s", str);        ac.Query(str);        for(int i = 1; i <= N; i++)        {            if(rec[i])                printf("%s: %d\n", dd[i], rec[i]);        }    }    return 0;}


 

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 碰到打呼噜的人怎么办 打呼吵得睡不着怎么办 打呼太吵睡不着怎么办 睡觉时舍友说话怎么办 夜晚醒了睡不着怎么办 夜晚怕黑睡不着怎么办 宝宝不愿意盖被子怎么办 白天睡觉晚上睡不着怎么办 晚上睡觉不安神怎么办 晚上经常睡不着觉怎么办 老是睡不着觉怎么办啊 小孩睡觉不安稳怎么办 睡觉时动不了怎么办 特别累还睡不着怎么办 又累又睡不着怎么办 干活累的睡不着怎么办 狗一有动静就叫怎么办 楼上天天闹动静怎么办 喝了奶茶失眠怎么办 失眠一宿第二天怎么办 睡觉外面噪音大怎么办 怀孕早期晚上睡不着怎么办 短发发尾翘怎么办 很累就是睡不着怎么办 人累但是睡不着怎么办 如果晚上睡不着该怎么办 晚上睡不着觉该怎么办 晚上睡不着该怎么办呢 晚上失眠睡不着该怎么办 晚上一直睡不着该怎么办 怀孕晚上睡不着该怎么办 运动太累睡不着怎么办 运动完睡不着觉怎么办 晚上冷得睡不着怎么办 晚上脚冷睡不着怎么办 短发头发有点乱怎么办 不想让别人睡觉怎么办 15岁晚上睡不着怎么办 16岁青少年失眠怎么办 好累又睡不着怎么办 造口患者拉肚子怎么办?