【题解】[JSOI2012]玄武密码
2022/3/29 23:26:24
本文主要是介绍【题解】[JSOI2012]玄武密码,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
题目链接
- 你谷:P5231[JSOI2012]玄武密码
- LOJ: #10058. 「一本通 2.4 练习 1」玄武密码
题意
输出模式串在文本串中能够匹配上的最长前缀。
输入格式
第一行有两个整数,\(N\)和\(M\),分别表示母串的长度和文字段的个数;
第二行是一个长度为\(N\)的字符串,所有字符都满足是 E,S,W 和 N 中的一个;
之后\(M\)行,每行有一个字符串,描述了一段带有玄武密码的文字。依然满足,所有字符都满足是 E,S,W 和 N 中的一个。
输出格式
输出有\(M\)行,对应\(M\)段文字。
每一行输出一个数,表示这一段文字的前缀与母串的最大匹配串长度。
思路
这是一道披上辣椒衣的AC自动机模板题。难点就在这层辣椒衣。
解决方法:先打标记,最后遍历。
代码实现
#include<cstdio> #include<queue> #include<cstring> #include<map> using namespace std; const int N=1e5+5; int n,m; int t[N*100][5],cnt,fail[N*100]; char s[N][105],txt[N*100]; bool vis[N*100]; map <char,int> mp; inline int ans(int x){ int p=0,ret=0; int l=strlen(s[x]); for(int i=0;i<l;i++){ int c=mp[s[x][i]]; p=t[p][c]; if(vis[p]) ret=i+1; } return ret; } inline void query(char x[]) { int p=0; for(int i=0; i<n; i++) { p=t[p][mp[x[i]]]; int j=p; while(j && (!vis[j])){ vis[j]=true; j=fail[j]; } } } inline void build_graph() { queue <int> q; for(int i=0; i<4; i++) { if(t[0][i]) q.push(t[0][i]); } while(!q.empty()) { int p=q.front(); q.pop(); for(int i=0; i<4; i++) { if(t[p][i]) { q.push(t[p][i]); fail[t[p][i]]=t[fail[p]][i]; } else t[p][i]=t[fail[p]][i]; } } } inline void ins(char x[]) { int l=strlen(x); int p=0; for(int i=0; i<l; i++) { int c=mp[x[i]]; if(!t[p][c]) t[p][c]=++cnt; p=t[p][c]; } } int main() { mp['E']=0; mp['S']=1; mp['W']=2; mp['N']=3; scanf("%d%d",&n,&m); scanf(" %s",txt); for(int i=1; i<=m; i++) { scanf(" %s",s[i]); ins(s[i]); } build_graph(); query(txt); for(int i=1; i<=m; i++) printf("%d\n",ans(i)); return 0; }
PS. 为了体验不能用万能头的感觉,没有用万能头。
反思:
必须承认,看了题解才写出看上去能算优美的代码。
一开始想要直接把trie的节点弄成包罗万象的大结点,就是说,把每个结点弄成大struct
,用每个结点映射它对应的模式串,包括记录它的深度,etc。然后发现写起来很头大。
看了一篇题解,发现可以通过先打标记,最后遍历的方法来确定能匹配的前缀长度。
这是一种存储数据解题(离线)的思维。
事实上,题目提示得很明显:先输入文本串,后输入模式串。这和一般AC自动机输入数据的顺序不同,或许提示着一种更自由地对待模式串的方式(指最后遍历一遍)。
这篇关于【题解】[JSOI2012]玄武密码的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-16Vue3资料:新手入门必读教程
- 2024-11-16Vue3资料:新手入门全面指南
- 2024-11-16Vue资料:新手入门完全指南
- 2024-11-16Vue项目实战:新手入门指南
- 2024-11-16React Hooks之useEffect案例详解
- 2024-11-16useRef案例详解:React中的useRef使用教程
- 2024-11-16React Hooks之useState案例详解
- 2024-11-16Vue入门指南:从零开始搭建第一个Vue项目
- 2024-11-16Vue3学习:新手入门教程与实践指南
- 2024-11-16Vue3学习:从入门到初级实战教程