这个题目要求在一个大矩阵里面匹配一个小矩阵,是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. Oracle自动备份bat

    很多时候我们需要自动备份数据库这边推荐bat+Windows计划任务实现 方案1 创建以下bat 然后添加到TaskSchedule(路径最好不要包含中文) @echo off @echo ===== ...

  2. Good Bye 2019

    A.Card Game 题目大意:两个人都有共有n张卡牌,每张卡牌上都有一个数xi,没有两张牌上的数相同,且xi不小于1不大于n.每次两个人选出一张牌来,牌上数字大的人赢得此局,如果谁最后手上拥有所有 ...

  3. WTL之手动编写框架窗口

    新版博客已经搭建好了,有问题请访问 htt://www.crazydebug.com 本人是一个实践主义者,不罗嗦上一篇工程搭建好以后,这一篇就开始写代码,写之前再说几句,如果你熟悉MFC分析过MFC ...

  4. QT事件处理–notify()

    转载至:https://www.deeplearn.me/349.html 一.说明 Qt 处理事件的方式之一:”继承 QApplication 并重新实现 notify()函数”.Qt 调用 QAp ...

  5. JVM探秘:JVM的参数类型

    本系列笔记主要基于<深入理解Java虚拟机:JVM高级特性与最佳实践 第2版>,是这本书的读书笔记. JVM的参数类型,大致可以分为标准参数.X参数.XX参数,而XX参数又可以分为Bool ...

  6. Essay写作观点的打造

    很多留学生在Essay写作过程中经常出现的问题就是缺乏对于已有知识的新的理解,只是单纯在做文献综述(literature review)而已.要怎么样才能够体现自己的理解和自己的观点,便是今天我们讲解 ...

  7. 报错SQL盲注之BIGINT 溢出

    首先感谢原创博主,在此致敬.本文转自:http://www.cnblogs.com/lcamry/articles/5509112.html MySQL版本在 5.5.5 及其以上 0x01 概述 我 ...

  8. 配置mysql时报错

    配置mysql时无法启动此程序,因为计算机丢失MSVCR100.dll. 去https://cn.dll-files.com/下载相应的版本 复制MSVCR100.dll 粘贴到下面 32位系统: 复 ...

  9. rsync错误

    rsync error:No route to host rsync服务端开启的iptables防火墙 [root@nfs01 tmp]# rsync -avz /etc/hosts rsync_ba ...

  10. Elasticsearch 教程

    章节 Elasticsearch 基本概念 Elasticsearch 安装 Elasticsearch 使用集群 Elasticsearch 健康检查 Elasticsearch 列出索引 Elas ...