这个题目要求在一个大矩阵里面匹配一个小矩阵,是AC自动机的灵活应用

思路是逐行按普通AC自动机匹配,用过counts[i][j]记录一下T字符矩阵以i行j列为开头的与P等大的矩阵区域 有多少行已经匹配了,显然如果该数值==p的行数,则说明匹配成功

就是在自动机的过程中,匹配得时候要稍微多想一下,每次匹配都要调用函数对 counts进行维护,以及还要注意某些行是相同的情况,用个链表保存,匹配成功后直接链过去继续对counts进行维护

最后统计counts里面有多少个值==p的行数即可得出结果

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = ;
char T[N][N];
char word[N][N];
int x,y,n,m;
int cnt,tr;
int recline[N];
int next[N];
int len[N];
int counts[N][N]; void process_match(int pos, int v) //对counts进行维护
{
int pr=recline[v-];
int c=pos-len[pr]+;//得到矩阵行和列的数值
while (pr>=){
if (tr>=pr){
counts[tr-pr][c]++;
}
pr=next[pr];//直接对下一个相同的行进行该操作
}
}
struct ACTrie
{
int ch[N*][];
int last[N*];
int val[N*];
int f[N*];
int sz;
int idx(char c){
return c-'a';
}
void init(){
memset(ch,,sizeof ch);
memset(last,,sizeof last);
memset(val,,sizeof val);
memset(f,,sizeof f);
sz=;
}
void insert(char*s,int v){
int u=;
for (int i=;s[i];i++){
int c=idx(s[i]);
if (!ch[u][c]){
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=v;
}
void getfail(){
queue<int> q;
for (int i=;i<;i++)
{
int u=ch[][i];
if (u) q.push(u);
}
while (!q.empty()){
int u=q.front();
q.pop();
for (int i=;i<;i++){
int v=ch[u][i];
if (!v) continue;
q.push(v);
int p=f[u];
while (p && !ch[p][i]) p=f[p];
f[v]=ch[p][i];
last[v]=val[f[v]]?f[v]:last[f[v]];
}
}
}
void report(int pos,int j){ //匹配函数要改一下,每次匹配成功都调用该函数对counts进行维护
if (j){
process_match(pos, val[j]);
report(pos, last[j]);
}
}
void find(char* str){
int u=;
for (int i=;str[i];i++){
int c=idx(str[i]);
while (u && !ch[u][c]) u=f[u];
u=ch[u][c];
if (val[u]){
report(i,u);
}
else if (last[u])
report(i,f[u]);
} } } ACT;
int main()
{
int t;
scanf("%d",&t);
while (t--){
scanf("%d%d",&x,&y);
for (int i=;i<x;i++){
scanf("%s",T[i]);
}
scanf("%d%d",&n,&m);
ACT.init();
for (int i=;i<n;i++){
scanf("%s",word[i]);
recline[i]=i;
next[i]=-;
len[i] = strlen(word[i]);
for (int j=;j<i;j++){
if (strcmp(word[i],word[j])==){
recline[i]=j;
next[i]=next[j]; //用链表的方式保存相同的行
next[j]=i;
break;
}
}
if (recline[i]==i){
ACT.insert(word[i],i+);
}
}
ACT.getfail();
memset(counts,,sizeof counts);
for (tr=;tr<x;tr++){
ACT.find(T[tr]);
}
int ans=;
for (int i=;i<x-n+;i++)
for (int j=;j<y-m+;j++){
//cout<<i<<" !! "<<j<<" "<<counts[i][j]<<endl;
if (counts[i][j]==n)
ans++;
}
printf("%d\n",ans);
}
return ;
}

UVA 11019 二维匹配 AC自动机的更多相关文章

  1. UVA 11019 Matrix Matcher(ac自动机)

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  2. 简单二维元胞自动机 MATLAB实现

    20世纪50年代,乌尔姆和冯·诺依曼(对此人真是崇拜的五体投地)为了研究机器人自我复制的可能性,提出了一种叫做元胞自动机(Cellular Automaton,CA)的算法.该算法采用局相互作用规则, ...

  3. [Alg] 文本匹配-多模匹配-AC自动机

    1. 简介 AC自动机是一种多模匹配的文本匹配算法. 如果采用naive的方法,即依次比较文本串s中是否包含模式串p1, p2,...非常耗时.考虑到这些模式串中可能具有相同子串,可以利用已经比较过的 ...

  4. uva 11178二维几何(点与直线、点积叉积)

    Problem D Morley’s Theorem Input: Standard Input Output: Standard Output Morley’s theorem states tha ...

  5. Substring Uva 11468_记忆化搜索 + AC自动机

    Code: #include<cstdio> #include<cstring> #include<queue> using namespace std; cons ...

  6. 字符串——AC自动机

    目录 一.前言 二.思路 三.代码 四.参考资料 一.前言 以前一直没学AC自动机,主要是被名字吓到了,自动AC,这么强的名字肯定很难,学了后才发现,其实不难. AC自动机并不是Acept autom ...

  7. 【BZOJ1030】[JSOI2007]文本生成器 AC自动机+动态规划

    [BZOJ1030][JSOI2007]文本生成器 Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文 ...

  8. BZOJ2553 [BeiJing2011]禁忌 【AC自动机 + dp + 矩乘优化】

    题目链接 BZOJ2553 题解 话说在前,此题卡精度,最好开long double 先建\(AC\)自动机 求期望,逆着求,设\(f[i][j]\)为长度为\(i\)的串,当前匹配AC自动机\(j\ ...

  9. 牛客新年AK场之模拟二维数组

    链接:https://ac.nowcoder.com/acm/contest/3800/D来源:牛客网 题目描述 Rinne 喜欢使用一种奇怪的方法背单词,现在这些单词被放在了一个 n×mn \tim ...

随机推荐

  1. idea-plugin-easycode

    1.背景 在练习使用mybatis-generator时候,无意间看到博文esaycode(代码神器),https://www.jianshu.com/p/e4192d7c6844,试验完,感觉这个工 ...

  2. ffmpeg 知识点

    ffmpeg FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.采用LGPL或GPL许可证.它提供了录制.转换以及流化音视频的完整解决方案.它包含了非常先进的音频/ ...

  3. 使用Picasso实现图片圆角和图片圆形

    作者很好的文章访问量缺很少也很难搜到(我这里插个眼以后用的到)作者:先知丨先觉 来源:CSDN 原文:https://blog.csdn.net/github_33304260/article/det ...

  4. python爬虫笔记01

    1.urllib库中request,parse的学习 1.1 简单的请求页面获取,并下载到本地 request的使用 from urllib import request # 获取此网页的demout ...

  5. Sass - &引用父选择器

    描述: 您可以使用&字符选择父级选择器. 它告诉父选择器应该插入的位置. 例一:&在前 h3 { font-size: 20px margin-bottom: 10px &.s ...

  6. python 小数相加报错 invalid literal for int() with base 10

    for i in column1: x = int(i) s += xprint "sum:",s,"count:",len(column1)# round ( ...

  7. spring的一些annotation

    通过使用spring的注解可以把一些类通过spring容器管理这些类 @controller 控制器(注入服务) @service 服务(注入dao) @repository dao(实现dao访问) ...

  8. 130-PHP子类通过类函数访问父类protected修饰的类成员

    <?php class father{ //定义father类 //定义protected修饰的成员属性和方法 protected $money=1000000; protected funct ...

  9. IDE一直在indexing, 造成系统卡死解决方法

    点击箭头指向,重启idea

  10. 【剑指Offer】面试题05.替换空格

    题目 请实现一个函数,把字符串 s 中的每个空格替换成"%20". 示例 1: 输入:s = "We are happy." 输出:"We%20are ...