分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 网页技术

[JSOI 2012] 玄武密码

发布时间:2023-09-06 02:11责任编辑:蔡小小关键词:暂无标签

[题目链接]

          https://www.lydsy.com/JudgeOnline/problem.php?id=4327

[算法]

        AC自动机
[代码]

        

#include<bits/stdc++.h>using namespace std;const int MAXN = 1e7 + 10;const int MAXM = 1e5 + 10;const int MAXLEN = 110;int n,m;int ans[MAXM];char P[MAXN];char s[MAXM][MAXLEN];inline int get_value(char a){ ???????if (a == ‘E‘) return 0; ???????if (a == ‘S‘) return 1; ???????if (a == ‘W‘) return 2; ???????if (a == ‘N‘) return 3;} struct AC_Automation{ ???????int tot; ???????int root; ???????struct Node ???????{ ???????????????int child[4]; ???????????????int fail; ???????????????bool visited; ???????} trie[MAXN]; ???????inline void insert(char *s) ???????{ ???????????????int now = root; ???????????????int len = strlen(s + 1); ???????????????????for (int i = 1; i <= len; i++) ???????????????{ ???????????????????????int val = get_value(s[i]); ???????????????????????if (!trie[now].child[val]) trie[now].child[val] = ++tot; ???????????????????????now = trie[now].child[val]; ???????????????????} ???????????} ???????????????inline void rebuild() ???????{ ???????????????int l,r; ???????????????static int q[MAXN]; ???????????????q[l = r = 1] = root; ???????????????trie[root].fail = -1; ???????????????while (l <= r) ???????????????{ ???????????????????????int cur = q[l]; ???????????????????????l++; ???????????????????????for (int i = 0; i < 4; i++) ???????????????????????{ ???????????????????????????????if (trie[cur].child[i]) ???????????????????????????????{ ???????????????????????????????????????if (cur == root) ???????????????????????????????????????????????trie[trie[cur].child[i]].fail = 0; ???????????????????????????????????????else ???????????????????????????????????????{ ???????????????????????????????????????????????int p = trie[cur].fail; ???????????????????????????????????????????????while (p != -1) ???????????????????????????????????????????????{ ???????????????????????????????????????????????????????if (trie[p].child[i]) ????????????????????????????????????????????????????????{ ???????????????????????????????????????????????????????????????trie[trie[cur].child[i]].fail = trie[p].child[i]; ???????????????????????????????????????????????????????????????break; ???????????????????????????????????????????????????????} else p = trie[p].fail; ???????????????????????????????????????????????} ???????????????????????????????????????} ???????????????????????????????????????q[++r] = trie[cur].child[i]; ????????????????????????????????} ???????????????????????} ???????????????} ???????} ???????inline void getans(char *s) ???????{ ???????????????int now = root; ???????????????int len = strlen(s + 1); ???????????????for (int i = 1; i <= len; i++) ???????????????{ ???????????????????????int val = get_value(s[i]); ???????????????????????int p = now; ???????????????????????while (p != -1) ???????????????????????{ ???????????????????????????????if (trie[p].child[val]) break; ???????????????????????????????else p = trie[p].fail; ???????????????????????} ???????????????????????if (p == -1) ????????????????????????{ ???????????????????????????????now = 0; ???????????????????????????????continue; ???????????????????????} else now = p = trie[p].child[val]; ???????????????????????while (p) ???????????????????????{ ???????????????????????????????if (!trie[p].visited) ???????????????????????????????{ ???????????????????????????????????????trie[p].visited = true; ???????????????????????????????????????p = trie[p].fail; ???????????????????????????????} else break; ???????????????????????} ???????????????} ???????} ???????inline void calc(int pos,char *s) ???????{ ???????????????int now = root; ???????????????int len = strlen(s + 1); ???????????????for (int i = 1; i <= len; i++) ???????????????{ ???????????????????????int val = get_value(s[i]); ???????????????????????now = trie[now].child[val]; ???????????????????????if (trie[now].visited) ans[pos] = i; ???????????????} ???????}} ACAM;int main() { ???????????????scanf("%d%d",&n,&m); ???????scanf("%s",P + 1); ???????for (int i = 1; i <= m; i++) scanf("%s",s[i] + 1); ???????for (int i = 1; i <= m; i++) ACAM.insert(s[i]); ???????ACAM.rebuild(); ???????ACAM.getans(P); ???????for (int i = 1; i <= m; i++) ACAM.calc(i,s[i]); ???????for (int i = 1; i <= m; i++) printf("%d\n",ans[i]); ???????????????return 0; ???}

[JSOI 2012] 玄武密码

原文地址:https://www.cnblogs.com/evenbao/p/9514949.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved