UVA 11019 Matrix Matcher AC自动机字符串矩阵匹配
2015-02-12 14:19
405 查看
题目大意:
就是在给出的N*M(1 <= N, M <= 1000) 的字符矩阵中寻找子矩阵X*Y(1 <= X, Y <= 100)出现的次数
大致思路:
白书例题= =
不过这种统计出现位置的方法还真是巧妙....需要注意当把X*Y的矩阵拆解的时候可能出现多行是一样的情况
细节见注释吧...
代码如下:
Result : Accepted Memory : ? KB Time : 2095 ms
就是在给出的N*M(1 <= N, M <= 1000) 的字符矩阵中寻找子矩阵X*Y(1 <= X, Y <= 100)出现的次数
大致思路:
白书例题= =
不过这种统计出现位置的方法还真是巧妙....需要注意当把X*Y的矩阵拆解的时候可能出现多行是一样的情况
细节见注释吧...
代码如下:
Result : Accepted Memory : ? KB Time : 2095 ms
/* * Author: Gatevin * Created Time: 2015/2/12 13:39:53 * File Name: Mononobe_Mitsuki.cpp */ #include<iostream> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<queue> #include<stack> #include<map> #include<set> #include<bitset> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cctype> #include<cmath> #include<ctime> #include<iomanip> using namespace std; const double eps(1e-8); typedef long long lint; int N, M, X, Y; char all[1010][1010]; char pat[110]; int match[1010][1010]; /* * 白书例题 * 用match[i][j]表示以(i, j)为左上角大小为X*Y的矩阵与模板矩阵X*Y有多少行匹配成功 * 先将子矩阵的各个行拆开插入Trie树建立AC自动机, 然后对于N*M矩阵的每行进行一次遍历 * 如果N*M矩阵的从第r行c列开始长度为Y的串出现匹配,则对与匹配到的原X*Y矩阵中的第k行 * 则将match[r][c - k + 1]加1, 就是这个地方的匹配位置统计感觉挺巧妙的 */ struct Trie { int next[10010][26], fail[10010]; vector <int> end[10010];//因为可能出现X*Y的矩阵中多个横行相同的情况,匹配位置需要用vector int L, root; int newnode() { for(int i = 0; i < 26; i++) next[L][i] = -1; end[L++].clear(); return L - 1; } void init() { L = 0; root = newnode(); return; } void insert(char *s, int id) { int now = root; for(; *s; s++) { if(next[now][*s - 'a'] == -1) next[now][*s - 'a'] = newnode(); now = next[now][*s - 'a']; } end[now].push_back(id); return; } void build() { fail[root] = root; queue <int> Q; Q.push(root); while(!Q.empty()) { int now = Q.front(); Q.pop(); for(int i = 0; i < 26; i++) if(next[now][i] == -1) next[now][i] = now == root ? root : next[fail[now]][i]; else { fail[next[now][i]] = now == root ? root : next[fail[now]][i]; Q.push(next[now][i]); } } return; } void query(char *s, int row) { int now = root; for(int col = 0; col < M; col++) { now = next[now][s[col] - 'a']; int tmp = now; while(tmp != root) { if(!end[tmp].empty())//第row行col - Y + 1列处出现了要找的子矩阵的end[tmp][i]列 for(unsigned int i = 0; i < end[tmp].size(); i++) if(row + 1 >= end[tmp][i]) match[row - end[tmp][i] + 1][col - Y + 1]++; tmp = fail[tmp]; } } return; } void solve() { memset(match, 0, sizeof(match)); for(int i = 0; i < N; i++) query(all[i], i); int ans = 0; for(int i = 0; i < N; i++) for(int j = 0; j < M; j++) if(match[i][j] == X) ans++; printf("%d\n", ans); return; } }; Trie AC; int main() { int t; scanf("%d", &t); while(t-->0) { scanf("%d %d", &N, &M); AC.init(); for(int i = 0; i < N; i++) scanf("%s", all[i]); scanf("%d %d", &X, &Y); for(int i = 1; i <= X; i++) scanf("%s", pat), AC.insert(pat, i); AC.build(); AC.solve(); } return 0; }
相关文章推荐
- UVA 11019 Matrix Matcher(AC自动机:矩阵匹配)
- [UVA11019] Matrix Matcher && AC自动机
- UVA 11019(Matrix Matcher-vector从迭代器中取值,AC自动机匹配字符矩阵)
- uva 11019 Matrix Matcher (ac自动机二维匹配)
- UVA 11019 Matrix Matcher(AC自动机矩阵匹配)
- UVA 11019 Matrix Matcher(ac自动机)
- [原创]字符串多模匹配算法之AC自动机理解心得
- UVA-11019Matrix Matcher(AC自动机)
- uva 11019 - Matrix Matcher(AC自动机)
- UVA 11019 Matrix Matcher(AC自动机)
- AC自动机(矩阵匹配)uva11019
- UVA 11019 Matrix Matcher(二维矩阵匹配ac自动机)
- UVA-11019 - Matrix Matcher(AC自动机)
- UVA 11019 Matrix Matcher 矩阵匹配器 AC自动机 二维文本串查找二维模式串
- 矩阵匹配 AC自动机 或 二维Hash UVa 11019 - Matrix Matcher
- uva11019 - Matrix Matcher 二维矩阵匹配 AC自动机
- UVa:11019 Matrix Matcher(AC自动机)
- UVA-11019 - Matrix Matcher(AC自动机)
- 字符串模板总结(一):AC自动机
- 字符串处理-AC自动机