UVA 11019 Matrix Matcher(二维矩阵匹配ac自动机)
来源:互联网 发布:淘宝 鸟枪暗语 编辑:程序博客网 时间:2024/05/30 05:05
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1960
题意:给出一个n×m
的矩阵一,在给出一个x×y
的矩阵二,求矩阵二在矩阵一中出现的次数。
思路:对于矩阵二的每行建立Trie,并在单词结尾结点记录走到该结点的为行数c(有多个可开数组记录),利用一个co[r][i]
数组记录在矩阵一中以(r, i)
为矩阵二的右上角,大小与矩阵二相同的矩阵包含的行数。对矩阵一每行均find()
一遍,最后扫描co
数组,统计值为x的个数。
注:AC自动机并不是最优解法,时间效率仍是较低,最优解法为二维hash。
代码:
#include <stdio.h>#include <iostream>#include <string.h>#include <math.h>#include <queue>#include <vector>using namespace std;const int SIZE = 3e2 + 10;const int N = 1e4 + 10;const int NN = 1e3 + 10;struct AC { int ch[N][SIZE]; int sz; int f[N]; bool ed[N]; int last[N]; int vt[N][SIZE]; int vn[N]; int co[NN][NN]; int newnode() { memset(ch[sz], 0, sizeof(ch[sz])); ed[sz] = false; f[sz] = 0; last[sz] = 0; vn[sz] = 0; return sz++; } void init() { memset(co, 0, sizeof(co)); sz = 0; newnode(); } void insert(int id, char *s) { int u = 0; int len = strlen(s); for (int i = 0; i < len; i++) { int idx = s[i]; if (!ch[u][idx]) ch[u][idx] = newnode(); u = ch[u][idx]; } ed[u] = true; vt[u][vn[u]++] = id; } void getfail() { queue<int> q; for (int i = 0; i < SIZE; i++) if (ch[0][i]) q.push(ch[0][i]); while (!q.empty()) { int u = q.front(); q.pop(); for (int i = 0; i < SIZE; i++) { int v = ch[u][i]; if (v) { q.push(v); int r = f[u]; while (r && !ch[r][i]) r = f[r]; f[v] = ch[r][i]; last[v] = (ed[f[v]] ? f[v] : last[f[v]]); } else { ch[u][i] = ch[f[u]][i]; } } } } void print(int r, int j, int c) { if (j) { for (int i = 0; i < vn[j]; i++) if (r >= vt[j][i]) co[r - vt[j][i]][c]++; print(r, last[j], c); } } void find(int r, char *s) { int u = 0; int len = strlen(s); for (int i = 0; i < len; i++) { int idx = s[i]; u = ch[u][idx]; if (ed[u]) print(r, u, i); else if (last[u]) print(r, last[u], i); } }}ac;char Mat[NN][NN];int main() { int t_case; scanf("%d", &t_case); for (int i_case = 1; i_case <= t_case; i_case++) { int n, m, x, y; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%s", Mat[i]); ac.init(); scanf("%d%d", &x, &y); for (int i = 1; i <= x; i++) { char str[SIZE]; scanf("%s", str); if (x <= n && y <= m) ac.insert(i, str); } int ans = 0; if (x <= n && y <= m) { ac.getfail(); for (int i = 1; i <= n; i++) ac.find(i, Mat[i]); for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) if (ac.co[i][j] == x) ans++; } printf("%d\n", ans); } return 0;}
0 0
- UVA 11019 Matrix Matcher(二维矩阵匹配ac自动机)
- UVa 11019 Matrix Matcher AC自动机 二维匹配
- UVA 11019 Matrix Matcher( 二维字符匹配 AC自动机 + DP)
- uva 11019 Matrix Matcher (ac自动机二维匹配)
- 矩阵匹配 AC自动机 或 二维Hash UVa 11019 - Matrix Matcher
- UVA 11019 Matrix Matcher(AC自动机矩阵匹配)
- UVA 11019 Matrix Matcher(AC自动机:矩阵匹配)
- UVA 11019 Matrix Matcher AC自动机字符串矩阵匹配
- UVA - 11019 Matrix Matcher (AC自动机(二维匹配) + dp)
- uva11019 - Matrix Matcher 二维矩阵匹配 AC自动机
- AC自动机(Matrix Matcher,UVA 11019)
- UVA-11019Matrix Matcher(AC自动机)
- UVA 11019(Matrix Matcher-vector从迭代器中取值,AC自动机匹配字符矩阵)
- UVa:11019 Matrix Matcher(AC自动机)
- uva 11019 - Matrix Matcher(AC自动机)
- uva 11019 - Matrix Matcher --AC自动机
- UVA-11019 - Matrix Matcher(AC自动机)
- UVA 11019 Matrix Matcher(AC自动机)
- Swift通过类名动态创建对象的方式
- FRM-40212:字段**的值无效
- Android系统性能调优工具介绍
- Ruby中Hash常用方法
- Java interview 统计一篇英文文档的单词数,并输出次数最多的10个
- UVA 11019 Matrix Matcher(二维矩阵匹配ac自动机)
- 使用递归对数组元素进行全排列
- 外链图片怎样搬到淘宝
- java synchronized详解
- 画图板的布局
- Android string.xml 显示特殊符号
- 高性能服务器设计——模块间通信
- Nginx 编译,添加未编译安装模块ngx_cache_purge
- Retrofit(2.0)入门小错误 -- Could not locate ResponseBody xxx Tried: * retrofit.BuiltInConverters