AC自动机 - Word Puzzles - POJ - 1204
发布日期:2021-05-07 19:58:59 浏览次数:12 分类:技术文章

本文共 3602 字,大约阅读时间需要 12 分钟。

AC自动机 - Word Puzzles - POJ - 1204

题意:

给 定 一 个 l × c 的 字 符 矩 阵 , 以 及 w 个 字 符 串 , 需 要 找 出 w 个 字 符 串 在 矩 阵 中 出 现 的 位 置 。 输 出 字 符 串 第 一 个 字 符 的 坐 标 以 及 字 符 串 的 “ 方 向 ” ( 共 8 个 方 向 ) , 由 8 个 字 母 A − H 表 示 8 个 方 向 , 从 A 开 始 代 表 北 , 顺 时 针 依 次 为 B , C , D , . . . , H 。 给定一个l×c的字符矩阵,以及w个字符串,需要找出w个字符串在矩阵中出现的位置。\\输出字符串第一个字符的坐标以及字符串的“方向”(共8个方向),\\由8个字母A-H表示8个方向,从A开始代表北,顺时针依次为B,C,D,...,H。 l×cww(8)8AH8AB,C,D,...,H

Sample Input:20 20 10QWSPILAATIRAGRAMYKEIAGTRCLQAXLPOIJLFVBUQTQTKAZXVMRWALEMAPKCWLIEACNKAZXKPOTPIZCEOFGKLSTCBTROPICALBLBCJEWHJEEWSMLPOEKORORALUPQWRNJOAAGJKMUSJAEKRQEIOLOAOQPRTVILCBZQOPUCAJSPPOUTMTSLPSFLPOUYTRFGMMLKIUISXSWWAHCPOIYTGAKLMNAHBVAEIAKHPLBGSMCLOGNGJMLLDTIKENVCSWQAZUAOEALHOPLPGEJKMNUTIIORMNCLOIUFTGSQACAXMOPBEIOQOASDHOPEPNBUYUYOBXBIONIAELOJHSWASMOUTRKHPOIYTJPLNAQWDRIBITGLPOINUYMRTEMPTMLMNBOPAFCOPLHAVAIANALBPFSMARGARITAALEMABARBECUETROPICALSUPREMALOUISIANACHEESEHAMEUROPAHAVAIANACAMPONESASample Output:0 15 G2 11 C7 18 A4 8 C16 13 B4 15 E10 3 D5 1 E19 7 C11 11 H

数据范围:

l , c , w ∈ [ 1 , 1000 ] 。 T i m e   l i m i t : 5000 m s   M e m o r y   l i m i t : 65536 k B l,c,w∈[1,1000]。\\Time \ limit:5000 ms\ Memory \ limit:65536 kB l,c,w[1,1000]Time limit:5000ms Memory limit:65536kB

题解:

对 k 个 字 符 串 建 T r i e 图 , 接 着 对 每 个 字 符 暴 力 搜 索 八 个 方 向 在 图 上 匹 配 , 记 下 匹 配 成 功 的 坐 标 和 方 向 即 可 。 对k个字符串建Trie图,接着对每个字符暴力搜索八个方向在图上匹配,记下匹配成功的坐标和方向即可。 kTrie

具体落实:

① 、 建 T r i e 图 , 插 入 的 过 程 中 给 每 个 结 尾 字 符 打 标 记 , 每 个 单 词 的 i d 记 为 其 输 入 的 序 号 , 方 便 匹 配 成 功 的 判 断 。 ② 、 爆 搜 的 过 程 可 以 从 矩 阵 四 条 边 上 的 点 进 入 , 来 减 少 重 复 搜 索 , 同 时 也 能 避 免 遗 漏 , 保 证 每 种 可 能 性 均 被 搜 到 。 ①、建Trie图,插入的过程中给每个结尾字符打标记,每个单词的id记为其输入的序号,方便匹配成功的判断。\\②、爆搜的过程可以从矩阵四条边上的点进入,来减少重复搜索,同时也能避免遗漏,保证每种可能性均被搜到。 Trieid便


代码:

#include 
#include
#include
#include
#include
const int N=1010;using namespace std;int l, c, idx = 1, w,ans[N][3], len[N];char s[N][N], s2[N],dir[N];int dx[] = { -1, -1, 0, 1, 1, 1, 0, -1 };int dy[] = { 0, 1, 1, 1, 0, -1, -1, -1 };struct node{ int tr[30], id, fail;}e[N * 110];void Insert(char *str,int x){ int u = 1; for (int i = 0;str[i]; i++) { int t = str[i] - 'A'; if (!e[u].tr[t]) e[u].tr[t] = ++idx; u = e[u].tr[t]; } e[u].id = x;}void build(){ for (int i = 0; i < 26; i++) e[0].tr[i] = 1; queue
q; q.push(1); while (!q.empty()) { int u = q.front(); q.pop(); int fail = e[u].fail; for (int i = 0; i < 26; i++) { int y = e[u].tr[i]; if (y) { e[y].fail = e[fail].tr[i]; q.push(y); } else e[u].tr[i] = e[fail].tr[i]; } }}void dfs(int sx, int sy, int d){ int x = sx, y = sy, u = 1; while (x >= 1 && x <= l && y >= 1 && y <= c) { while (u && !e[u].tr[s[x][y] - 'A']) u = e[u].fail; u = e[u].tr[s[x][y] - 'A']; if (e[u].id) { ans[e[u].id][1] = x - (len[e[u].id] - 1) * dx[d]; ///回到第一个字母 ans[e[u].id][2] = y - (len[e[u].id] - 1) * dy[d]; dir[e[u].id] = d; } x += dx[d]; y += dy[d]; }}int main(){ scanf("%d%d%d", &l, &c, &w); for (int i = 1; i <= l; i++) scanf("%s", s[i] + 1); for (int i = 1; i <= w; i++) { scanf("%s", s2); len[i] = strlen(s2); Insert(s2,i); } build(); for (int i = 1; i <= l; i++) for (int j = 0; j < 8; j++) dfs(i, 1, j), dfs(i, c, j); for (int i = 1; i <= c; i++) for (int j = 0; j < 8; j++) dfs(1, i, j), dfs(l, i, j); for (int i = 1; i <= w; i++) printf("%d %d %c\n", ans[i][1] - 1, ans[i][2] - 1, dir[i] + 'A'); return 0;}
上一篇:Trie - Dr. Evil Underscores - CodeForces - 1285D
下一篇:AC自动机(Trie图模板) - Keywords Search - hdu 2222

发表评论

最新留言

感谢大佬
[***.8.128.20]2025年03月30日 20时00分42秒