题面

【题目描述】
在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河。相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中。老人们说,这是玄武神灵将天书藏匿在此。
很多年后,人们终于在进香河地区发现了带有玄武密码的文字。更加神奇的是,这份带有玄武密码的文字,与玄武湖南岸台城的结构有微妙的关联。于是,漫长的破译工作开始了。
经过分析,我们可以用东南西北四个方向来描述台城城砖的摆放,不妨用一个长度为 NNN 的序列来描述,序列中的元素分别是 E,S,W,NE,S,W,NE,S,W,N,代表了东南西北四向,我们称之为母串。而神秘的玄武密码是由四象的图案描述而成的 MMM 段文字。这里的四象,分别是东之青龙,西之白虎,南之朱雀,北之玄武,对东南西北四向相对应。
现在,考古工作者遇到了一个难题。对于每一段文字,其前缀在母串上的最大匹配长度是多少呢?
【输入】
第一行有两个整数,NNN 和 MMM,分别表示母串的长度和文字段的个数;
第二行是一个长度为 N 的字符串,所有字符都满足是 E,S,W和NE,S,W 和 NE,S,W和N中的一个;
之后 M 行,每行有一个字符串,描述了一段带有玄武密码的文字。依然满足,所有字符都满足是 E,S,W 和 N 中的一个
【输出】
输出有 M 行,对应M 段文字。
每一行输出一个数,表示这一段文字的前缀与母串的最大匹配串长度。
【样例输入】

7 3
SNNSSNS
NNSS
NNN
WSEE

【样例输出】

4
2
0

【提示】
对于全部数据,1≤N≤107,1≤M≤1051≤N≤10^7,1≤M≤10^51≤N≤107,1≤M≤105,保证每一段文字的长度均小于等于 100100100。

算法分析

题目简单来说就是寻找MMM个字符串在长度为NNN的母串中出现的最长的长缀。
对MMM个字符串建立TrieTrieTrie字典树,使用ACACAC自动机在树上进行匹配,在匹配是,对匹配到的所有点进行标记。
最后再在树上遍历一遍MMM个字符,查看每个字符串中深度最大的标记,即为出现的最长的前缀长度。
时间复杂度:O(107)O(10^7)O(107)

参考程序

#include<bits/stdc++.h>
using namespace std;
const int N=10000010;
int trie[N][4],tot=1,vis[N],nxt[N];
int n,m;
char s[N],s2[100005][105];
queue<int> q;
int f(char ch)
{if(ch=='E') return 0;if(ch=='S') return 1;if(ch=='W') return 2;return 3;
}void built(int k)
{int len=strlen(s2[k]);int u=1;        //根节点for(int i=0;i<len;i++){int v=f(s2[k][i]);if(trie[u][v]==0)   trie[u][v]=++tot;//根节点为1,tot初始化一定设为1 u=trie[u][v];   } vis[u]++;       //结束标记
}
void bfs()
{      for(int i=0;i<=3;i++)//初始化{int v=trie[1][i];if(v) nxt[v]=1,q.push(v);   //根节点的孩子结点nxt指向根节点 else trie[1][i]=1;          //优化,不存在直接又从1开始 } while(!q.empty()){int u=q.front();q.pop();for(int i=0;i<=3;i++)    {int v=trie[u][i];if(v==0)    trie[u][i]=trie[nxt[u]][i];     //优化,如果不存在则指向nxt[u]相同字符转移边,就不用再递归去找nxt[u]else{q.push(v);nxt[v]=trie[nxt[u]][i];         //存在,u的转移边结点v等于nxt[u]相同转移边的结点}}}
}
void find()
{int u=1;int len=strlen(s);for(int i=0;i<len;i++){int v=f(s[i]);u=trie[u][v];                           //优化后不需要判断是否存在结点u的转移边for(int j=u;j!=1&&vis[j]!=-1;j=nxt[j])  //统计,j为根节点或者已经统计过结束 {vis[j]=-1;                          //标记出现过 }}
}
int Find(int k)
{int len=strlen(s2[k]);int u=1;        //根节点int deep=0,i=0,ans=0;while(i<len){int v=f(s2[k][i]);u=trie[u][v];deep++;i++; if(vis[u]==-1)  ans=deep;   //记录深度最大的标记,即最长前缀 }   return ans;
}
int main()
{scanf("%d%d",&n,&m);scanf("%s",s);for(int i=1;i<=m;i++){scanf("%s",s2[i]);built(i);}bfs();  find();for(int i=1;i<=m;i++)printf("%d\n",Find(i)); return 0;
}

【题解】「JSOI2012」玄武密码(AC自动机)相关推荐

  1. 【BZOJ4327】JSOI2012 玄武密码 AC自动机

    [BZOJ4327]JSOI2012 玄武密码 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香 ...

  2. 【bzoj4327】JSOI2012 玄武密码 AC自动机

    题目描述 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神灵将天书藏匿在此.  很多年后,人们 ...

  3. bzoj4327: JSOI2012 玄武密码 AC自动机

    bzoj4327: JSOI2012 玄武密码 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香 ...

  4. BZOJ 4327 [JSOI2012]玄武密码 (AC自动机)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=4327 题解: 做法挺显然,建出AC自动机之后在上面跑,标记所有走过的点,然后再进行递推 ...

  5. BZOJ 4327 【JSOI 2012】 玄武密码 AC自动机+dfs

    题目描述 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神灵将天书藏匿在此.  很多年后,人们 ...

  6. BZOJ_4327_JSOI2012 玄武密码_AC自动机

    BZOJ_4327_JSOI2012 玄武密码_AC自动机 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便 ...

  7. 洛谷 P-4045 密码(AC自动机+状态压缩+数位DP+乱搞)

    洛谷 P-4045 密码 记AC的第一道黑题! 题意:已知一段密码包含了一些字符串,然后求满足条件的密码有多少个,数量小于42时还得全部输出 思路: 一开始WA了两个点,不知道WA的什么,索性把读入的 ...

  8. [JSOI2009]密码——AC自动机+记忆化搜索(状压)

    题面 Bzoj1559 解析  要求一个能包含所有字符串的串的个数,联想到AC自动机. 每一个节点需要存一个终点信息,即以这个点为结尾的字符串编号,这个需要开一个vector来存,因为一个节点需要继承 ...

  9. 提高篇 第二部分 字符串算法 第4章 AC自动机

    https://blog.csdn.net/wangyh1008/article/details/81428056 [模板]AC自动机(加强版) 洛谷3796 AC自动机_A_loud_name-CS ...

最新文章

  1. intval0.57100 php_php中0,'',null,false,true,FLASE,TREU,array()的相等恒等学习
  2. 3D中的OBJ文件格式详解(转载)
  3. Oracle已从2019年1月起收取Java费用
  4. Flask搭建二进制音频传送接口
  5. RTX3090深度学习环境配置(PyTorch1.8)
  6. Xilinx IOdelay--Virtex-5介绍
  7. C++输入输出:cin/cout 还是 scanf/printf?
  8. IIS 伪静态下 利用PHP获取 网址后缀
  9. 基于FPGA的RGB图像转 Ycbcr图像实现 gray图像
  10. 清华大学操作系统OS学习(五)——物理内存管理:非连续内存分配
  11. 单片机0 99c语言程序,单片机C语言程序设计实训99例.doc
  12. openbci脑电帽3d打印文件下载
  13. 非科班程序员AI学习路径建议
  14. 让机器辨别气味:利用图神经网络预测分子的嗅觉属性
  15. 服务器的cd驱动器怎么修改盘符,更改dvd驱动器盘符,cd驱动器盘符改
  16. 关于软件产品化的几点思考【转】
  17. cmd 连接 远程数据库
  18. missing ios distribution signing identity xxx, xcode can request one for you
  19. 判断ip是内网还是外网, 判断请求来之pc还是mobile
  20. MathJax中那些挺难找到的符号表示汇总

热门文章

  1. CentOSnbsp;下mysqlnbsp;ERRORamp;n…
  2. lanmp centOS7 一键式 搭建配置
  3. C语言_统计单词长度
  4. 同样是码农,收入差距怎么这么大呢?
  5. linux当中shadow文件的作用,解释Linux中passwd与shadow文件
  6. IMX6ULL系列学习记录-sii902x移植篇
  7. BoredApeYachtClub 无聊猿-NFT 源码解析第一节
  8. S32DS Components组件配置
  9. 白加黑加载方式_“白加黑减”即曝光补偿的应用方法及原理全面详解——致新手新新手...
  10. JMS RabbitMQ消息代理