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. pugixml

    http://www.firedragonpzy.com.cn/index.php/archives/3227 有关cocos2d-x的xml文件读取问题

  2. android UI生成器

    可根据选择的效果生成资源 http://jgilfelt.github.io/android-actionbarstylegenerator/#name=example&compat=sher ...

  3. Java基础知识强化之IO流笔记31:转换流出现的原因和格式

    1. 由于字节流操作中文不是特别方便,所以Java就提供了转换流.  字符流 = 字节流 + 编码表 2. 编码表 由字符及其对应数值组成的一张表 常见的编码表: • ASCII/Unicode字符集 ...

  4. Java设计模式--单列设计模式

    设计模式:解决某一类问题行知最有效的方法.java有23种设计模式 单列设计模式: 解决一个类在内存中只存在一个对象 思路:(要保证对象的唯一性) 1.为了避免其它程序建立该对象,先禁止替他类创建改对 ...

  5. Asp.Net MVC Ajax

    将ASP.NET MVC中的form提交改为ajax提交 在ASP.NET MVC视图中通过 @using (Html.BeginForm()) 产生的是form表单提交代码,可以用javascrip ...

  6. 第1条:了解Objective-C 语言的起源

    1.OC语言是由Smalltalk演化而来.该语言使用“消息结构” 而 非“函数调用”. 使用“消息结构”的语言,其运行时所执行的代码由运行环境来决定: 编译器不需要关心接收消息的对象是什么类型,只在 ...

  7. 配置wamp开发环境【1】

    新手在PHP网站建设时,会使用使用PHP的集成开发环境,这样利于开发和理解!但是做为一个网站开发人员,会独立的配置开发环境这是必须的……因为集成的环境毕竟是固定的,不利于自己的开发.好,废话少说咱现在 ...

  8. Qt5下的常见问题————C1083

    很多像我一样刚开始学习Qt的时候都会遇到这样的问题.例如"fatal error C1083: 无法打开包括文件:“QApplication”: No such file or direct ...

  9. KMP算法——字符串匹配

    正直找工作面试巅峰时期,有幸在学校可以听到July的讲座,在时长将近三个小时的演讲中,发现对于找工作来说,算法数据结构可以算是程序员道路的一个考量吧,毕竟中国学计算机的人太多了,只能使用这些方法来淘汰 ...

  10. 『重构--改善既有代码的设计』读书笔记----Change Reference to Value

    如果你有一个引用对象,很小且不可改变,而且不易管理,你就需要考虑将他改为一个值对象.在Change Value to Reference我们说过,要在引用对象和值对象之间做选择,有时候并不容易,有了重 ...