Description

Given an N × M matrix, your task is to find the number of occurences of an X × Y pattern.

Input
The first line contains a single integer t (t ≤ 15), the number of test cases.
For each case, the first line contains two integers N and M (N, M ≤ 1000). The next N lines
contain M characters each.
The next line contains two integers X and Y (X, Y ≤ 100). The next X lines contain Y characters
each.

Output

For each case, output a single integer in its own line, the number of occurrences.

Sample Input

2
1 1
x
1 1
y
3 3
abc
bcd
cde
2 2
bc
cd


Sample Output
0
2

【题意】

  在二维文本串T中查找一个二维模板串P出现了多少次。

【分析】

  拆分模板串P的每一行,建AC自动机。

  拆分文本串T的每一行,在自动机中与P匹配,ct[i][j]表示以点(i,j)为左上角、与P等大的矩形有多少个对应的行与P匹配。
  最后ct[i][j]==P的行数的i,j就是一个匹配点,ans++。
  

  注意:1.原本我在trie的叶子用动态数组维护了一个表示这一行是P的第几行的数组,但是超时了,后来看了LRJ的代码,改成了用一个nt[i]来表示重复的行的下一行,就A了。
  2.注意在ct[i][j]里加的时候判断i,j是否大于0.

代码如下:

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define Maxn 1010
#define Maxl 110
#define INF 0xfffffff int n,m,l,r;
int ct[Maxn][Maxn],nt[Maxl];
char s[Maxn][Maxn];
char ss[Maxn]; struct node
{
int fail,mark;
int son[];
}t[Maxn*Maxn];int tot; void upd(int x)
{
t[x].mark=;
memset(t[x].son,,sizeof(t[x].son));
} void read_trie(int tk)
{
scanf("%s",s[]+);
int len=strlen(s[]+);
for(int i=;i<=len;i++) ss[i]=s[][len-i+];
int now=;
for(int i=;i<=len;i++)
{
int ind=ss[i]-'a'+;
if(!t[now].son[ind])
{
t[now].son[ind]=++tot;
upd(tot);
}
now=t[now].son[ind];
if(i==len)
{
if(t[now].mark) nt[tk]=t[now].mark;//我好搞笑
t[now].mark=tk;
}
}
} queue<int > q;
void build_AC()
{
while(!q.empty()) q.pop();
q.push();
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=;i<=;i++)
{
if(t[x].son[i])
{
t[t[x].son[i]].fail=x?t[t[x].fail].son[i]:;
q.push(t[x].son[i]);
}
else t[x].son[i]=t[t[x].fail].son[i];
}
if(t[t[x].fail].mark) t[x].mark=t[t[x].fail].mark;
}
} void add(int x,int y,int z)
{
if(x-z+>=) ct[x-z+][y]++;
if(nt[z]!=) add(x,y,nt[z]);
} void ffind()
{
int now;
memset(ct,,sizeof(ct));
for(int i=;i<=n;i++)
{
now=;
for(int j=m;j>=;j--)
{
now=t[now].son[s[i][j]-'a'+];
if(t[now].mark) add(i,j,t[now].mark);
}
}
int ans=;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(ct[i][j]==l) ans++;
printf("%d\n",ans);
} void init()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%s",s[i]+);
tot=;upd();
scanf("%d%d",&l,&r);
memset(nt,,sizeof(nt));
for(int i=;i<=l;i++)
{
read_trie(i);
}
build_AC();
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
ffind();
}
return ;
}

[UVA11019]

2016-07-12 15:37:53

【UVA11019】Matrix Matcher的更多相关文章

  1. 【BZOJ4128】Matrix BSGS+hash

    [BZOJ4128]Matrix Description 给定矩阵A,B和模数p,求最小的x满足 A^x = B (mod p) Input 第一行两个整数n和p,表示矩阵的阶和模数,接下来一个n * ...

  2. 【RS】Matrix Factorization Techniques for Recommender Systems - 推荐系统的矩阵分解技术

    [论文标题]Matrix Factorization Techniques for Recommender Systems(2009,Published by the IEEE Computer So ...

  3. 【poj2155】Matrix(二维树状数组区间更新+单点查询)

    Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the ...

  4. 【数学】Matrix Multiplication

                                 Matrix Multiplication Time Limit: 2000MS   Memory Limit: 65536K Total S ...

  5. 【UVA11082】Matrix Decompressing(有上下界的网络流)

    题意:给出一个矩阵前i列所有元素的和,和前j行所有元素的和,求这个矩阵解压以后的原型.(答案不唯一) n,m<=20,1<=a[i,j]<=20 思路:这道题把边上的流量作为原先矩阵 ...

  6. 【BNUOJ19500】 Matrix Decompressing

    https://www.bnuoj.com/v3/problem_show.php?pid=19500 (题目链接) 题意 给出一个R行C列的正整数矩阵,设前${A_i}$项为其前i行所有元素之和,$ ...

  7. 【题解】Matrix BZOJ 4128 矩阵求逆 离散对数 大步小步算法

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4128 大水题一道 使用大步小步算法,把数字的运算换成矩阵的运算就好了 矩阵求逆?这么基础的线 ...

  8. 题解【POJ2155】Matrix

    Description Given an \(N \times N\) matrix \(A\), whose elements are either \(0\) or \(1\). \(A[i, j ...

  9. 【poj3233】 Matrix Power Series

    http://poj.org/problem?id=3233 (题目链接) 题意 给出一个n×n的矩阵A,求模m下A+A2+A3+…+Ak 的值 Solution 今日考试就A了这一道题.. 当k为偶 ...

随机推荐

  1. 追踪CPU跑满 堆栈调试

    http://blog.donghao.org/2014/04/24/%E8%BF%BD%E8%B8%AAcpu%E8%B7%91%E6%BB%A1/

  2. HDU2088JAVA2

    Box of Bricks Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  3. 卸载AMH 5.0面板的具体办法

    安装AMH 5.0面板只有YES.NO和EXIT,和AMH 4.X的安装.卸载.退出有点不同,那么如何卸载AMH 5.0面板呢? 1.root登录ssh 2.输入如下命令: killall php-f ...

  4. spring参数类型异常输出(二), SpringMvc参数类型转换错误输出(二)

    spring参数类型异常输出(二), SpringMvc参数类型转换错误输出(二) >>>>>>>>>>>>>>&g ...

  5. ( 转 )Github配置

    以下转自 http://liuzhijun.iteye.com/blog/1457207 有问题请联系我删除. -----———————————————————————— 如果你的代码不知道放哪里好, ...

  6. Java-Android 之Hello World

    1.新建一个Android Project 2.2版本的 修改values下面的内容,为: <?xml version="1.0" encoding="utf-8& ...

  7. ArcGIS 设置地图显示范围大小

    Arcmap的FullExtent默认是地图加载的时候的extent.其实这个fullExtent是可以设置的. 打开ArcMap,选择左边图例的Layers ,右键点击,选择“Properties. ...

  8. 学习java随笔第九篇:java异常处理

    在java中的异常处理和c#中的异常处理是一样的都是用try-catch语句. 基本语法如下 try { //此处是可能出现异常的代码 } catch(Exception e) { //此处是如果发生 ...

  9. Android开发手记(17) 数据存储二 文件存储数据

    Android为数据存储提供了五种方式: 1.SharedPreferences 2.文件存储 3.SQLite数据库 4.ContentProvider 5.网络存储 本文主要介绍如何使用文件来存储 ...

  10. java中获得IP地址

    public class IPTest { public static void main(String[] args) { try{ // 获取计算机名 String name = InetAddr ...