UVA 11019 二维匹配 AC自动机
这个题目要求在一个大矩阵里面匹配一个小矩阵,是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自动机的更多相关文章
- UVA 11019 Matrix Matcher(ac自动机)
题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- 简单二维元胞自动机 MATLAB实现
20世纪50年代,乌尔姆和冯·诺依曼(对此人真是崇拜的五体投地)为了研究机器人自我复制的可能性,提出了一种叫做元胞自动机(Cellular Automaton,CA)的算法.该算法采用局相互作用规则, ...
- [Alg] 文本匹配-多模匹配-AC自动机
1. 简介 AC自动机是一种多模匹配的文本匹配算法. 如果采用naive的方法,即依次比较文本串s中是否包含模式串p1, p2,...非常耗时.考虑到这些模式串中可能具有相同子串,可以利用已经比较过的 ...
- uva 11178二维几何(点与直线、点积叉积)
Problem D Morley’s Theorem Input: Standard Input Output: Standard Output Morley’s theorem states tha ...
- Substring Uva 11468_记忆化搜索 + AC自动机
Code: #include<cstdio> #include<cstring> #include<queue> using namespace std; cons ...
- 字符串——AC自动机
目录 一.前言 二.思路 三.代码 四.参考资料 一.前言 以前一直没学AC自动机,主要是被名字吓到了,自动AC,这么强的名字肯定很难,学了后才发现,其实不难. AC自动机并不是Acept autom ...
- 【BZOJ1030】[JSOI2007]文本生成器 AC自动机+动态规划
[BZOJ1030][JSOI2007]文本生成器 Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文 ...
- BZOJ2553 [BeiJing2011]禁忌 【AC自动机 + dp + 矩乘优化】
题目链接 BZOJ2553 题解 话说在前,此题卡精度,最好开long double 先建\(AC\)自动机 求期望,逆着求,设\(f[i][j]\)为长度为\(i\)的串,当前匹配AC自动机\(j\ ...
- 牛客新年AK场之模拟二维数组
链接:https://ac.nowcoder.com/acm/contest/3800/D来源:牛客网 题目描述 Rinne 喜欢使用一种奇怪的方法背单词,现在这些单词被放在了一个 n×mn \tim ...
随机推荐
- Quartus设计FIR滤波器的系数文件格式(适用于FIR II的IP核)
对常用的FIR,我们使用MATLAB的fdatool(或者filterDesigner) 设计滤波器,给定指标,生成系数.为了方便,我们将系数保存到文件,其保存格式比较简介,在此进行说明. 1.FIR ...
- Linux学习《第四章脚本》20200222
- 学校算法作业X——(日期问题)
最近一直在忙项目,难得有时间写一下作业,所以断了,现在赶紧续上 题目如下: 日历问题 问题描述 在我们现在使用的日历中, 闰年被定义为能被4整除的年份,但是能被100整除而不能被400整除的年是例外, ...
- yum相关变量浅析
问题背景 同事发现一台centos7机器的yum repo不能使用,现象为相关的repo的meta文件下载失败,提示相关meta文件的下载路径有问题. 问题分析 通过终端输出的报错,发现是/etc/y ...
- centos下安装tomcat8.
一.tomcat安装之前,首先安装java jdk,所以手首先将相关安装包都下载传到虚拟机上 1.下载java的linux----jdk1.8安装 到官网上下载与本虚拟机版本位相适应的位节数的Linu ...
- VMware Workstation上新建虚拟机
准备开始,话不多少,直接上图 点击创建新的虚拟机或者在文件上面选择新建虚拟机 点击完成就可以了 后面的步骤,是在公司电脑上完成的,新建了一个CentOs1,步骤同上,后面继续,然后需要更改配置,点击虚 ...
- R apply()函数
创建一个列表变量,它的第一个元素包含所有从0到9的平方数,第二个元素为10到19之内的所有平方数,依此类推,最后一个元素为90到99之内的平方数.没有平方数的元素也应该被包含在内! 学习网友的解题思路 ...
- [LeetCode] 930. Binary Subarrays With Sum 二元子数组之和
In an array A of 0s and 1s, how many non-empty subarrays have sum S? Example 1: Input: A = [1,0,1,0, ...
- StackExchange.Redis.DLL 操作redis加强版
直接引用StackExchange.Redis.dll这一个dll来操作redis App.config配置 <?xml version="1.0" encoding=&qu ...
- XML 之 语法详解
一.文档规则 .区分大小写. .属性值必须加引号(单引号.双引号都可以),一般情况下建议使用使用双引号. .所有标记必须有结束符号. .所有空标记必须关闭. .必须有且仅有一根元素. .解析空白字符时 ...