UVa 11019 Matrix Matcher 字符矩阵出现次数

来源:互联网 发布:外网访问内网mac服务器 编辑:程序博客网 时间:2024/05/21 21:34

题目来源:UVa 11019 Matrix Matcher

题意:输入2个字符矩阵 求第二个字符矩阵在第一个字符矩阵中出现的次数

思路:见大白书218页

#include <cstdio>#include <cstring>#include <queue>#include <vector>using namespace std;const int maxn = 1010;const int maxm = 110;char a[maxn][maxn];char b[maxm][maxm];int cnt[maxn][maxn];int n, m, x, y;const int maxnode = 1000*1000+100;const int size = 26;int val[maxnode];int ch[maxnode][size];int f[maxnode];int last[maxnode];int sz;vector <int> G[maxnode];void init(){sz = 1;memset(ch[0], 0, sizeof(ch[0]));memset(cnt, 0, sizeof(cnt));val[0] = 0;last[0] = 0;G[0].clear();memset(f, 0, sizeof(f));}void insert(char *s, int v){int u = 0;for(int i = 0; i < y; i++){int c = s[i] - 'a';if(!ch[u][c]){memset(ch[sz], 0, sizeof(ch[sz]));val[sz] = 0;G[sz].clear();ch[u][c] = sz++;}u = ch[u][c];}val[u]++;G[u].push_back(v);}void getFail(){queue <int> Q;f[0] = 0;for(int c = 0; c < size; c++){int u = ch[0][c];if(u){f[u] = 0;Q.push(u);}}while(!Q.empty()){int r = Q.front(); Q.pop();for(int c = 0; c < size; c++){int u = ch[r][c];if(!u){ch[r][c] = ch[f[r]][c];continue;}Q.push(u);int v = f[r];while(v && !ch[v][c])v = f[v];f[u] = ch[v][c];last[u] = val[f[u]] ? f[u] : last[f[u]]; }}}void find(){for(int i = 0; i < n; i++){int u = 0;for(int j = 0; j < m; j++){int c = a[i][j] - 'a';u = ch[u][c];if(!val[u] && !last[u])continue;int v = val[u] ? u : last[u];while(v){for(int k = 0; k < G[v].size(); k++){if(i-G[v][k] >= 0)cnt[i-G[v][k]][j-y+1]++;}v = last[v];}}}int ans = 0;for(int i = 0; i < n; i++)for(int j = 0; j < m; j++)if(cnt[i][j] == x)ans++;printf("%d\n", ans);}int main(){int T;scanf("%d", &T);while(T--){init();scanf("%d %d", &n, &m);for(int i = 0; i < n; i++){scanf("%s", a[i]);}scanf("%d %d", &x, &y);for(int i = 0; i < x; i++){scanf("%s", b[i]);insert(b[i], i);}getFail();find();}return 0;}/*21 1x1 1y3 3abcbcdcde2 2bccd*/


 

0 0