HDU 3065 病毒侵袭持续中(AC自动机)
这题数据太水,一开始没有加上Get的方法也能AC。。话说AC自动机中一定要注意加上Get的方法!(不然,同一个后缀的其他单词就没被算上了。)
代码如下:
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>
#include <string>
#include <map>
#include <iostream>
using namespace std;
const int MAX_N = + ;
const int MAX_Tot = * + ; int ans[+];
map<int,string> M; struct Aho
{
struct state
{
int nxt[];
int fail,cnt;
}stateTable[MAX_Tot]; int size; queue<int> que; void init()
{
while(que.size()) que.pop();
for(int i=;i<MAX_Tot;i++)
{
memset(stateTable[i].nxt,,sizeof(stateTable[i].nxt));
stateTable[i].fail = stateTable[i].cnt = ;
}
size = ;
} void insert(char *s,int which)
{
int n = strlen(s);
int now = ;
for(int i=;i<n;i++)
{
char c = s[i];
if(!stateTable[now].nxt[c-'A'])
stateTable[now].nxt[c-'A'] = size++;
now = stateTable[now].nxt[c-'A'];
}
stateTable[now].cnt = which;
} void build()
{
stateTable[].fail = -;
que.push(); while(que.size())
{
int u = que.front();que.pop();
for(int i=;i<;i++)
{
if(stateTable[u].nxt[i])
{
if(u == ) stateTable[stateTable[u].nxt[i]].fail = ;
else
{
int v = stateTable[u].fail;
while(v != -)
{
if(stateTable[v].nxt[i])
{
stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
break;
}
v = stateTable[v].fail;
}
if(v == -) stateTable[stateTable[u].nxt[i]].fail = ;
}
que.push(stateTable[u].nxt[i]);
}
}
}
} void Get(int u)
{
while(u)
{
ans[stateTable[u].cnt] ++;
u = stateTable[u].fail;
}
} void match(char *s)
{
int n = strlen(s);
int now = ;
for(int i=;i<n;i++)
{
char c = s[i];
if(c<'A' || c>'Z') {now = ;continue;}
if(stateTable[now].nxt[c-'A']) now = stateTable[now].nxt[c-'A'];
else
{
int p = stateTable[now].fail;
while(p != - && stateTable[p].nxt[c-'A'] == ) p = stateTable[p].fail;
if(p == -) now = ;
else now = stateTable[p].nxt[c-'A'];
}
if(stateTable[now].cnt)
{
Get(now);
//ans[stateTable[now].cnt] ++;
/*
一定要用Get这样的方法,
不然,同一个后缀的无法被算上了
*/
}
}
}
}aho; int n;
char s[MAX_N]; int main()
{
while(scanf("%d",&n)==)
{
memset(ans,,sizeof(ans));
M.clear();
aho.init();
for(int i=;i<=n;i++)
{
scanf("%s",s);
M[i] = s;
aho.insert(s,i);
}
aho.build();
scanf("%s",s);
aho.match(s);
for(int i=;i<=n;i++)
{
if(ans[i])
{
cout << M[i] << ": " << ans[i] << endl;
}
}
}
}
————————————————————————————————————————————
发现上面的代码有问题(虽然能AC),正确代码如下:
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>
#include <string>
#include <map>
#include <iostream>
using namespace std;
const int MAX_N = + ;
const int MAX_Tot = * + ; int ans[+];
map<int,string> M; struct Aho
{
struct state
{
int nxt[];
int fail,cnt;
}stateTable[MAX_Tot]; int size; queue<int> que; void init()
{
while(que.size()) que.pop();
for(int i=;i<MAX_Tot;i++)
{
memset(stateTable[i].nxt,,sizeof(stateTable[i].nxt));
stateTable[i].fail = stateTable[i].cnt = ;
}
size = ;
} void insert(char *s,int which)
{
int n = strlen(s);
int now = ;
for(int i=;i<n;i++)
{
char c = s[i];
if(!stateTable[now].nxt[c-'A'])
stateTable[now].nxt[c-'A'] = size++;
now = stateTable[now].nxt[c-'A'];
}
stateTable[now].cnt = which;
} void build()
{
stateTable[].fail = -;
que.push(); while(que.size())
{
int u = que.front();que.pop();
for(int i=;i<;i++)
{
if(stateTable[u].nxt[i])
{
if(u == ) stateTable[stateTable[u].nxt[i]].fail = ;
else
{
int v = stateTable[u].fail;
while(v != -)
{
if(stateTable[v].nxt[i])
{
stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
break;
}
v = stateTable[v].fail;
}
if(v == -) stateTable[stateTable[u].nxt[i]].fail = ;
}
que.push(stateTable[u].nxt[i]);
}
}
}
} void Get(int u)
{
while(u)
{
ans[stateTable[u].cnt] ++;
u = stateTable[u].fail;
}
} void match(char *s)
{
int n = strlen(s);
int now = ;
for(int i=;i<n;i++)
{
char c = s[i];
if(c<'A' || c>'Z') {now = ;continue;}
if(stateTable[now].nxt[c-'A']) now = stateTable[now].nxt[c-'A'];
else
{
int p = stateTable[now].fail;
while(p != - && stateTable[p].nxt[c-'A'] == ) p = stateTable[p].fail;
if(p == -) now = ;
else now = stateTable[p].nxt[c-'A'];
}
//if(stateTable[now].cnt)
{
Get(now);
}
}
}
}aho; int n;
char s[MAX_N]; int main()
{
while(scanf("%d",&n)==)
{
memset(ans,,sizeof(ans));
M.clear();
aho.init();
for(int i=;i<=n;i++)
{
scanf("%s",s);
M[i] = s;
aho.insert(s,i);
}
aho.build();
scanf("%s",s);
aho.match(s);
for(int i=;i<=n;i++)
{
if(ans[i])
{
cout << M[i] << ": " << ans[i] << endl;
}
}
}
}
/*
3
ABCDEFG
ABCDE
DEF
ABCDEFG
*/
HDU 3065 病毒侵袭持续中(AC自动机)的更多相关文章
- HDU 3065 病毒侵袭持续中 (AC自动机)
题目链接 Problem Description 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒 ...
- hdoj 3065 病毒侵袭持续中(AC自动机)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 思路分析:问题需要模式匹配多个模式串,需要注意的是模式串会包含和重叠,需要对AC自动机的匹配过 ...
- HDU 3065 病毒侵袭持续中
HDU 3065 病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 3065 病毒侵袭持续中【AC自动机】
<题目链接> 题目大意: 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的“万恶之源”.这是一个庞大的病毒网站,他有着好多好多的病毒,但是 ...
- HDU 3065 病毒侵袭持续中(AC自己主动机)
题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=3065 Problem Description 小t非常感谢大家帮忙攻克了他的上一个问题.然而病毒侵袭 ...
- hdu3065 病毒侵袭持续中 AC自动机入门题 N(N <= 1000)个长度不大于50的模式串(保证所有的模式串都不相同), 一个长度不大于2000000的待匹配串,求模式串在待匹配串中的出现次数。
/** 题目:hdu3065 病毒侵袭持续中 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065 题意:N(N <= 1000)个长度不大于50的 ...
- hdu----(3065)病毒侵袭持续中(AC自动机)
病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- hdu 3065病毒侵袭持续中
病毒侵袭持续中 http://acm.hdu.edu.cn/showproblem.php?pid=3065 Time Limit: 2000/1000 MS (Java/Others) Mem ...
- HDU 3065 病毒侵袭持续中 (模板题)
病毒侵袭持续中 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 ...
随机推荐
- ionic-native-transitions调用原生页面切换实现ionic路由切换
废话不多说:ionic-native-transitions调用原生页面切换实现ionic路由切换,从而大大提升ionic应用的性能. ionic-native-transitions是一个ionic ...
- AngularJS之手动加载模块app和controller
使用ng的页面中一般都是使用模块自动加载,页面的结构一般是这样的 加载angularjs脚本 加载业务代码脚本(或者写在script标签中) html结构代码(带有ng指令) 就像这样 app.htm ...
- RabbitMQ中 exchange、route、queue的关系
从AMQP协议可以看出,MessageQueue.Exchange和Binding构成了AMQP协议的核心,下面我们就围绕这三个主要组件 从应用使用的角度全面的介绍如何利用Rabbit MQ构建 ...
- 一个链式调用 setTimeout的例子
<div> 现在时间是:<input type="text" id="name1" size="16" value=&qu ...
- 【转】vc++MCF/C++/C中怎样让应用程序获得或以管理员权限运行 ,ShellExecuteEX编程 --- 获取管理员权限
ShellExecuteEX编程 --- 获取管理员权限:http://blog.csdn.net/jhui163/article/details/5873027 怎样让你的应用程序获得管理员权限:就 ...
- HTML5播放器
seweise palyer http://www.whatled.com/m/?post=1626 https://github.com/sewise/sewise-player2 七牛云音视频支持 ...
- mac osx 制作安装u盘
制作OS X El Capitan 原版安装U盘:sudo /Applications/Install\ OS\ X\ El\ Capitan.app/Contents/Resources/creat ...
- java对象序列化byte[] and byte[]反序列化对象--转
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOExceptio ...
- -include和sinclude 作用
-include和sinclude 如果有文件没有找到的话,make会生成一条警告信息,但不会马上出现致命错误.它 会继续载入其它的文件,一旦完成makefile的读取,make会再重试这些没有找 ...
- ADF_Data Binding系列3_使用Placeholder Data Control
2015-02-16 Created By BaoXinjian