这个题目要求在一个大矩阵里面匹配一个小矩阵,是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. 066、Java面向对象之以分步的方式实例化对象

    01.代码如下: package TIANPAN; class Book { // 定义一个新的类 String title; // 书的名字 double price; // 书的价格 public ...

  2. SwiftUI中多设备运行方法

    https://blog.csdn.net/weixin_42679753/article/details/94465674 https://www.jianshu.com/p/17fc7929fcb ...

  3. [题解] LuoguP2764 最小路径覆盖问题

    传送门 好久没做网络流方面的题发现自己啥都不会了qwq 题意:给一张有向图,让你用最少的简单路径覆盖所有的点. 考虑这样一个东西,刚开始,我们有\(n\)条路径,每条路径就是单一的一个点,那么我们的目 ...

  4. Day4-T1

    原题目 Hades 与 Dionysus 在狂饮后玩起了多米诺骨牌的小游戏. 现在桌上有 N 块多米诺骨牌,每块多米诺骨牌上半部分和下半部分上都有一个整数.每次翻转可让 一块多米诺骨牌上下翻转,即上下 ...

  5. python3调用微软js引擎ChakraCore

    有关ChakraCore介绍请移步:https://github.com/Microsoft/ChakraCore 使用案例GitHub源码:https://github.com/pyAppman/C ...

  6. 十一、SAP文本变量,并设置长度

    一.在SAP中,一个中文占用2个文本长度,详见代码: 二.效果如下

  7. mysql多表连接查询

    新建两张表: 表1:student  截图如下: 表2:course  截图如下: (此时这样建表只是为了演示连接SQL语句,当然实际开发中我们不会这样建表,实际开发中这两个表会有自己不同的主键.) ...

  8. 实验吧-密码学-这里没有key(VBScript脚本加密)

    打开网页,查看源代码,发现一段乱码,这就是加密后的密文. #@~^TgAAAA=='[6*liLa6++p'aXvfiLaa6i[[avWi[[a*p[[6*!I'[6cp'aXvXILa6fp[:6 ...

  9. jsp页面使用<% 语句%> SQL Server数据库报空指针异常(在控制台可以正常执行)

    一直反感用SQL Server数据库,很影响电脑性能!!数据库作业不得不用 前几天作业一直报空指针异常: 自己检查了所传参数,和数组不为空 数据库查询语句不为空 然后查看SQL服务是否启动  主要是S ...

  10. python 网页爬虫 基础篇

    首先要连接自己的数据库 import pymysql import requests #需要导入模块 db = pymysql.connect('localhost', 'root', '****** ...