uva-1449-AC自动机
题目链接https://vjudge.net/problem/UVA-1449
题目大意:给出N(N<150)个长度不超过L(70)的匹配串和一个长度小于1e6的文本串,在文本串中找出出现次数最多的匹配串,如果有多个匹配串满足条件,按输入顺序依次输出。
AC自动机复杂度约为O((N+M)*L) //N为匹配串个数,M为文本串长度,L为匹配串平均长度,时间3s,可行
用了两个map方便统计字符串出现的次数和根据节点编号找到对应的字符串,注意这里统计时不必将AC[u].cnt清零;
#include<bits/stdc++.h>
using namespace std;
const int MAX_T=;
const int MAX_NOD=*+;
const int MAX_SIG=;
const int MAX_P=;
map<string,int> M;
map<int,string> _M;
char T[MAX_T];
struct node{
int next[MAX_SIG];
int fail,cnt;
};
struct aho
{
node AC[MAX_NOD];
int size; int idx(char c){return c-'a';} void init()
{
for(int i=;i<MAX_NOD;++i)
memset(AC[i].next,,sizeof(AC[i].next)),AC[i].cnt=;
size=;
AC[].fail=-;
} void insert(char *S)
{
int n=strlen(S);
int u=;
for(int i=;i<n;++i)
{
int c=idx(S[i]);
if(!AC[u].next[c]) AC[u].next[c]=size++;
u=AC[u].next[c];
}
AC[u].cnt++;
_M[u]=S;
//cout<<"---"<<_M[u]<<" "<<AC[u].cnt<<endl;
} void build_fail()
{
queue<int> q;
q.push();
AC[].fail=-;
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=;i<MAX_SIG;++i)
{
if(AC[u].next[i]){
if(!u) AC[AC[u].next[i]].fail=;
else{
int v=AC[u].fail;
while(v!=-&&AC[v].next[i]==) v=AC[v].fail;
if(v==-) AC[AC[u].next[i]].fail=;
else AC[AC[u].next[i]].fail=AC[v].next[i];
}
q.push(AC[u].next[i]);
}
}
}
} void cal(int u)
{
while(u!=-){//cout<<"ppp"<<endl;
M[_M[u]]+=AC[u].cnt;
// AC[u].cnt=0;
u=AC[u].fail;
}
} int solve(char *T)
{
int now=;
int n=strlen(T);
for(int i=;i<n;++i)
{
int c=idx(T[i]);
if(AC[now].next[c]) now=AC[now].next[c];
else{
int v=AC[now].fail;
while(v!=-&&AC[v].next[c]==) v=AC[v].fail;
if(v==-){now=;}
else{
now=AC[v].next[c];
}
}
if(AC[now].cnt){
cal(now);
}
}
}
};
int main()
{
int n;
char P[MAX_P];
string x[];
while(cin>>n&&n){
M.clear();
_M.clear();
aho a;
a.init();
for(int i=;i<=n;++i)
{
cin>>P;
x[i]=P;
M[P]=;
a.insert(P);
}
cin>>T;
a.build_fail();
int ans=;
a.solve(T);
for(int i=;i<=n;++i)
ans=max(ans,M[x[i]]);
cout<<ans<<endl;
for(int i=;i<=n;++i)
{
if(M[x[i]]==ans) cout<<x[i]<<endl;
}
}
return ;
}
/*
2
aba
bab
ababababac
6
beta
alpha
haha
delta
dede
tata
dedeltalphahahahototatalpha
0
*/
uva-1449-AC自动机的更多相关文章
- Uva 11468 AC自动机或运算
AC自动机 UVa 11468 题意:给一些字符和各自出现的概率,在其中随机选择L次,形成长度为L的字符串S,给定K个模板串,求S不包含任意一个串的概率. 首先介绍改良版的AC自动机: 传统的AC自动 ...
- UVa 11468 (AC自动机 概率DP) Substring
将K个模板串构成一个AC自动机,那些能匹配到的单词节点都称之为禁止节点. 然后问题就变成了在Tire树上走L步且不经过禁止节点的概率. 根据全概率公式用记忆化搜索求解. #include <cs ...
- UVA - 11468 (AC自动机+动态规划)
建立AC自动机,把AC自动机当做一张图,在上面跑L个节点就行了. 参考了刘汝佳的代码,发现可能有一个潜在的Bug--如果模式串中出现了没有指定的字符,AC自动机可能会建立出错. 提供一组关于这个BUG ...
- Substring UVA - 11468 AC自动机+概率DP
题意: 给出一些字符和各自对应的选择概率,随机选择L次后得到一个长度为L的随机字符串S. 给出K个模板串,计算S不包含任何一个模板串的概率 dp[i][j]表示走到AC自动机 i 这个节点 还需要走 ...
- UVA 11468 AC 自动机
首先我们应该是枚举 L个位置上的每个字符来得到最终概率 然后AC自动机的作用就是为了判断你枚举的地方是否对应了单词节点,如果对应了,就肯定要不得 #include <iostream> # ...
- UVa 11019 (AC自动机 二维模式串匹配) Matrix Matcher
就向书上说得那样,如果模式串P的第i行出现在文本串T的第r行第c列,则cnt[r-i][c]++; 还有个很棘手的问题就是模式串中可能会有相同的串,所以用repr[i]来记录第i个模式串P[i]第一次 ...
- UVA 11468 AC自动机入门题 记忆化概率dp+ac自动机
/** 链接:https://vjudge.net/problem/UVA-11468 详见lrj训练指南P218 我的是反向求存在模板串的概率. dp[i][j]表示当前i位置选择字符,前面i-1个 ...
- uva 11468 AC自动机+概率DP
#include<cstdio> #include<cstring> #include<queue> #include<cstdio> #include ...
- UVa 1449 - Dominating Patterns (AC自动机)
题目大意:给出多个字符串模板,并给出一个文本串,求在文本串中出现最多的模板,输出最多的次数并输出该模板(若有多个满足,则按输入顺序输出). 思路:赤裸裸的 AC自动机,上模板. 代码: #includ ...
- UVA 11019 Matrix Matcher(ac自动机)
题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
随机推荐
- 实战docker,编写Dockerfile定制tomcat8镜像,实现web应用在线部署
最初在tomcat上部署web应用的方式,是通过maven的maven-compiler-plugin插件先打成war包,再将war包复制到tomcat的webapps目录下,后来用上了tomcat7 ...
- 【我的Android进阶之旅】如何去除ListView中Header View、Footer View中的分割线
最近的项目中给ListView 加入了一个Header View之后,发现Header View的下方也有了分割线,很难看,UI要求将Header View的分割器去掉,好吧.现在就来说一说如何如何去 ...
- DRF(2) - 解析器,序列化组件使用(GET/POST接口设计)
一.DRF - 解析器 1.解析器的引出 我们知道,浏览器可以向django服务器发送json格式的数据,此时,django不会帮我们进行解析,只是将发送的原数据保存在request.body中,只有 ...
- Django - 自定义分页、FBV和CBV
一.自定义分页(优势在于能够保存搜索条件) """ 分页组件使用示例: 1) 先取出所有数据USER_LIST 2) 实例化: obj = Pagination(requ ...
- Python3+Selenium3自动化测试-(四)
selenium鼠标事件 # coding=utf-8 import time from selenium import webdriver from selenium.webdriver.commo ...
- Android图片加载框架Picasso最全使用教程5
在之前的四篇博客中,我们学习了所有的关于Picasso的主要方法,我们也对这个Picasso有了一个很深的认识,下面就主要对Picasso自身进行分析,这样的话,会让我们更了解Picasso的核心方法 ...
- oracle external密码验证
什么是external密码验证 当OS user 中存在和DB user 同名的用户时 直接使用和DB user 同名的OS user 可以不输入密码直接登录数据库, [oracle@zxrac1 ...
- Web框架简介
Web框架本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...
- 在python中有多少种运算符?解释一下算术运算符
在python中,我们有7种运算符:算术运算符.关系运算符.赋值运算符.逻辑运算符.位运算符.成员运算符.身份运算符 我们有7个算术运算符,能让我们对数值进行算术计算 1.加号(+),将两个值相加 2 ...
- JAVA垃圾回收笔记
一.分析GC日志 /** * @author : Hejinsheng * @date : 2019/1/18 0018 * @Description: 模拟FULL GC/YOUNG GC * -X ...