AC自动机---病毒侵袭持续中
HDU 3065
题目网址: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=110773#problem/C
Description
Input
接下来N行,每行表示一个病毒特征码,特征码字符串长度在1―50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。
在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。
Output
病毒特征码: 出现次数
冒号后有一个空格,按病毒特征码的输入顺序进行输出。
Sample Input
AA
BB
CC
ooxxCC%dAAAoen....END
Sample Output
CC: 1
Hint
Hit: 题目描述中没有被提及的所有情况都应该进行考虑。比如两个病毒特征码可能有相互包含或者有重叠的特征码段。 计数策略也可一定程度上从Sample中推测。 思路: 这题要注意多组输入,上一题不用多组输入就过了,这题居然必须多组输入…… 还有要注意每个测试样例结束后要要将结构体空间清理掉,否则会超内存。 解题过程,在AC自动机模板上在结构体中加一个标记,用来标记模式串(病毒的特征码)的序号。在计数过程中,不用把模式串标记为-1,因为要重复计数。 代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 50010
char str[],keyword[][];
int head,tail;
int C[]; struct node
{
node *fail;
node *next[];
int b;
int count;
node()
{
fail=NULL;
b=;
count=-;
for(int i=; i<; i++)
next[i]=NULL;
}
}*q[N];
node *root; void insert(char *str,int x) ///建立Trie
{
int temp,len;
node *p=root;
len=strlen(str);
for(int i=; i<len; i++)
{
temp=str[i]-;
if(p->next[temp]==NULL)
p->next[temp]=new node();
p=p->next[temp];
}
p->count++;
p->b=x;///在该串结束字符位置标记该串的序号;
} void setfail() ///使用bfs初始化fail指针;
{
q[tail++]=root;
while(head!=tail)
{
node *p=q[head++];
node *temp=NULL;
for(int i=; i<; i++)
if(p->next[i]!=NULL)
{
if(p==root) ///首字母的fail必指向根
p->next[i]->fail=root;
else
{
temp=p->fail; ///失败指针
while(temp!=NULL) ///2种情况结束:匹配为空or找到匹配
{
if(temp->next[i]!=NULL) ///找到匹配
{
p->next[i]->fail=temp->next[i];
break;
}
temp=temp->fail;
}
if(temp==NULL) ///为空则从头匹配
p->next[i]->fail=root;
}
q[tail++]=p->next[i]; ///入队(p->next[i]的fail指针已设置m完);
}
}
} void query()
{
int index,len;
node *p=root;
len=strlen(str);
for(int i=; 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; ///p不动,temp计算后缀串
while(temp!=root&&temp->count!=-)
{
C[temp->b]++;
temp=temp->fail;
}
}
return ;
} void free_(node *r)
{
for(int i=;i<;i++)
{
if(r->next[i])
free_(r->next[i]);
}
free(r);
} int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
memset(C,,sizeof(C));
getchar();
head=tail=;
root=new node();
for(int i=; i<=n; i++)
{
gets(keyword[i]);
insert(keyword[i],i);
}
setfail();
gets(str);
query();
for(int i=; i<=n; i++)
if(C[i]) printf("%s: %d\n",keyword[i],C[i]);
free_(root);///释放开辟的结构体空间;
}
return ;
}
AC自动机---病毒侵袭持续中的更多相关文章
- AC日记——病毒侵袭持续中 hdu 3065
3065 思路: 好题: 代码: #include <queue> #include <cstdio> #include <cstring> using names ...
- 【HDU3065】 病毒侵袭持续中(AC自动机)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...
- hdu3065 病毒侵袭持续中 AC自动机入门题 N(N <= 1000)个长度不大于50的模式串(保证所有的模式串都不相同), 一个长度不大于2000000的待匹配串,求模式串在待匹配串中的出现次数。
/** 题目:hdu3065 病毒侵袭持续中 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065 题意:N(N <= 1000)个长度不大于50的 ...
- hdu 3065 病毒侵袭持续中【AC自动机】
<题目链接> 题目大意: 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的“万恶之源”.这是一个庞大的病毒网站,他有着好多好多的病毒,但是 ...
- hdu3065 病毒侵袭持续中【AC自动机】
病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- HDU3065 病毒侵袭持续中 —— AC自动机
题目链接:https://vjudge.net/problem/HDU-3065 病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
- 病毒侵袭持续中 HDU - 3065 AC自动机
小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒网站,他有着好多好多的病毒,但是这个网站包含的病毒 ...
- hdu----(3065)病毒侵袭持续中(AC自动机)
病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- HDU 3065 病毒侵袭持续中 (AC自动机)
题目链接 Problem Description 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒 ...
随机推荐
- hdu1251在词典里统计前缀出现的个数
banana band bee absolute acm ba b band abc #include<iostream> using namespace std; //数据结构 s ...
- [AX2012]Claims user
AX2012可以创建一种account type为claims user的账号,这种账号不需要在AD中事先已创建用户,但是claims账号是无法通过rich client登陆到AX,它的主要应用场景是 ...
- [转载]在 JavaScript 中判断“空值”
http://lync.in/check-empty-value-in-javascript/ 有时候我们会遇到这样的情况:在一些前端控件要提交数据到服务器端的数据验证过程中,需要判断提交的数据是否为 ...
- 查看、关闭某一runlevel下自动启动的服务
这些服务都在 /etc/init.d/ 目录下 1.查看 chkconfig --list | grep '3:on' Auditd - 安全审计工具: blk-availability 如果使用LV ...
- AppScan学习笔记
AppScan学习笔记 http://www.docin.com/p-777386896.html
- 锁屏上显示Activity
在Android中,有些比较强的提醒,需要用户紧急处理的内容.需要唤醒屏幕,甚至在锁定屏幕的情况下,也要显示出来.例如,来电界面和闹钟提醒界面.这是怎样实现的呢? 其实,实现起来非常简单.只要给Act ...
- 免费WebService服务
国内手机号码归属地查询:http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx 中国股票及时行情数据:http://webservi ...
- PHP cURL应用实现模拟登录与采集使用方法详解
对于做过数据采集的人来说,cURL一定不会陌生.虽然在PHP中有file_get_contents函数可以获取远程链接的数据,但是它的可控制性太差了,对于各种复杂情况的采集情景,file_get_co ...
- MySQL数据库之数据类型BOOL/BOOLEAN与TINYINT测试总结
From: http://database.51cto.com/art/201203/323863.htm 网络上很多人咨询mysql是否提供布尔类型?MySQL数据库确实提供布尔类型,此数据类型的关 ...
- javaScript数据类型与typeof操作符
1,typeof操作符. typeof操作符是用来检测变量的数据类型.使用:typeof 变量名;返回以下字符串: 字符串 描述 undefined 未定义 boolean 布尔值 string 字 ...