思路

AC自动机匹配二维模式串的题目

因为如果矩形匹配,则每一行都必须匹配,考虑对于一个点,设count[i][j]记录以它为左上角的与模式矩形大小相同的矩形中有多少行和模式矩形匹配

然后把模式矩形的每一行插入AC自动机中,把文本矩形的每一行在上面跑,如果文本矩形第i行和模式矩形第c行匹配,匹配位置是j,则更新 counts[i-c+1][j+1-y+1]

最后每个count[i][j]等于x的(i,j)就是一个符合条件的点

小心重复的模式串。

代码

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <cstring>
  4. #include <queue>
  5. #include <vector>
  6. using namespace std;
  7. int Trie[10100][26],fail[10100],counts[1010][1010],root,Nodecnt,x,y,n,m;
  8. char s[1010][1010],t[110][110];
  9. vector<int> isend[10100];
  10. void insert(char *s,int len,int inq){
  11. int o=root;
  12. for(int i=0;i<len;i++){
  13. if(!Trie[o][s[i]-'a'])
  14. Trie[o][s[i]-'a']=++Nodecnt;
  15. o=Trie[o][s[i]-'a'];
  16. }
  17. isend[o].push_back(inq);
  18. }
  19. queue<int> q;
  20. void build_AC(void){
  21. for(int i=0;i<26;i++){
  22. if(Trie[root][i]){
  23. fail[Trie[root][i]]=root;
  24. q.push(Trie[root][i]);
  25. }
  26. }
  27. while(!q.empty()){
  28. int x=q.front();
  29. q.pop();
  30. for(int i=0;i<26;i++){
  31. if(Trie[x][i]){
  32. fail[Trie[x][i]]=Trie[fail[x]][i];
  33. q.push(Trie[x][i]);
  34. }
  35. else
  36. Trie[x][i]=Trie[fail[x]][i];
  37. }
  38. }
  39. }
  40. void query(char *s,int len,int inq){
  41. int o=root;
  42. for(int i=0;i<len;i++){
  43. o=Trie[o][s[i]-'a'];
  44. int p=o;
  45. while(p){
  46. if((isend[p].size()))
  47. for(int j=0;j<isend[p].size();j++)
  48. if((inq-isend[p][j]+1)>=1&&(i+1-y+1>=1))
  49. counts[inq-isend[p][j]+1][i+1-y+1]++;
  50. p=fail[p];
  51. }
  52. }
  53. }
  54. void init(void){
  55. memset(Trie,0,sizeof(Trie));
  56. memset(fail,0,sizeof(fail));
  57. memset(counts,0,sizeof(counts));
  58. for(int i=0;i<=Nodecnt;i++)
  59. isend[i].clear();
  60. Nodecnt=0;
  61. root=0;
  62. }
  63. int main(){
  64. freopen("test.in","r",stdin);
  65. freopen("test.out","w",stdout);
  66. int T;
  67. Nodecnt=0;
  68. root=0;
  69. scanf("%d",&T);
  70. while(T--){
  71. scanf("%d %d",&n,&m);
  72. for(int i=1;i<=n;i++)
  73. scanf("%s",s[i]);
  74. scanf("%d %d",&x,&y);
  75. for(int i=1;i<=x;i++){
  76. scanf("%s",t[i]);
  77. insert(t[i],y,i);
  78. }
  79. build_AC();
  80. for(int i=1;i<=n;i++){
  81. query(s[i],m,i);
  82. }
  83. int ans=0;
  84. for(int i=1;i<=n;i++)
  85. for(int j=1;j<=m;j++)
  86. if(counts[i][j]==x)
  87. ans++;
  88. printf("%d\n",ans);
  89. init();
  90. }
  91. return 0;
  92. }

UVA11019 Matrix Matcher的更多相关文章

  1. UVA11019 Matrix Matcher【hash傻逼题】【AC自动机好题】

    LINK1 LINK2 题目大意 让你在一个大小为\(n*m\)的矩阵中找大小是\(x*y\)的矩阵的出现次数 思路1:Hash hash思路及其傻逼 你把一维情况扩展一下 一维是一个bas,那你二维 ...

  2. UVA11019 Matrix Matcher (AC自动机)

    二维的矩阵匹配,把模式矩阵按列拆开构造AC自动机,记录行号(为了缩点判断). 把T矩阵按行匹配,一旦匹配成功,在假想的子矩阵左上角位置加一.最后统计总数. 因为所有模式串长度一样,不用维护last数组 ...

  3. UVA 11019 Matrix Matcher 矩阵匹配器 AC自动机 二维文本串查找二维模式串

    链接:https://vjudge.net/problem/UVA-11019lrjP218 matrix matcher #include<bits/stdc++.h> using na ...

  4. UVA11019 Martix Matcher --- AC自动机

    UVA11019 Martix Matcher 题目描述: 给定一个\(n*m\)的文本串 问一个\(x*y\)的模式串出现的次数 AC自动机的奇妙使用 将\(x*y\)的模式串拆分成x个串,当x个串 ...

  5. 【UVA11019】Matrix Matcher

    Description Given an N × M matrix, your task is to find the number of occurences of an X × Y pattern ...

  6. AC自动机(二维) UVA 11019 Matrix Matcher

    题目传送门 题意:训练指南P218 分析:一行一行的插入,一行一行的匹配,当匹配成功时将对应子矩阵的左上角位置cnt[r][c]++;然后统计 cnt[r][c] == x 的数量 #include ...

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

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

  8. UVa 11019 (AC自动机 二维模式串匹配) Matrix Matcher

    就向书上说得那样,如果模式串P的第i行出现在文本串T的第r行第c列,则cnt[r-i][c]++; 还有个很棘手的问题就是模式串中可能会有相同的串,所以用repr[i]来记录第i个模式串P[i]第一次 ...

  9. uva 11019 Matrix Matcher

    题意:给出一个n*m的字符矩阵T,你的任务是找出给定的x*y的字符矩阵P在T中出现了多少次. 思路:要想整个矩阵匹配,至少各行都得匹配.所以先把P的每行看做一个模式串构造出AC自动机,然后在T中的各行 ...

随机推荐

  1. SQL特殊字符转义

    原文链接: SQL特殊字符转义 应 该说,您即使没有处理 HTML 或 JavaScript 的特殊字符,也不会带来灾难性的后果,但是如果不在动态构造 SQL 语句时对变量中特殊字符进行处理,将可能导 ...

  2. loadrunner笔记(三):设置、运行场景和生成测试报告

    //上一篇的代码有点问题,问题出在 web_reg_find()函数中,这个函数简单的说是搜索下一步操作的请求对象(html)页面中是否存在相应的文本字符串.所以用在登录操作中,它搜索的是主页.htm ...

  3. 剑指offer——python【第30题】连续子数组的最大和

    题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量 ...

  4. JAVA SE ------------------- 项目的菜单输入

    //写一个工具类,进行输入选项数值的获取public class InputUtil { static Scanner sc=new Scanner(System.in); public static ...

  5. ERP项目实施记录10

    好久没有更新,因为进度一直拖着.已经实施了20个月了,很多东西没有开发出来.原因多方面的,虽然在此打算吐槽一下开发公司,但其实很大部分责任还是在我们自己. 不多说了,看图:

  6. redash学习记录

    一.简介 一款开源的 BI 工具Redash 二.参考资料 一款开源的 BI 工具Redash 浅析数据查询与可视化工具--Redash

  7. Ubuntu软件安装和查看已安装相关知识

    说明:由于图形化界面方法(如Add/Remove... 和Synaptic Package Manageer)比较简单,所以这里主要总结在终端通过命令行方式进行的软件包安装.卸载和删除的方法.一.Ub ...

  8. mysql使用存储过程和event定期删除

    -- 创建存储过程DELIMITER //CREATE PROCEDURE del_data()BEGIN DELETE FROM t_route_status WHERE route_date &l ...

  9. 什么是Rollback Segment(已truncate和delete 命令为例)?

    Rollback Segments是在你数据库中的一些存储空间,它用来临时的保存当数据库数据发生改变时的先前值,Rollback Segment主要有两个目的: 1. 如果因为某种原因或者其他用用户想 ...

  10. C++11 std::call_once:保证函数在任何情况下只调用一次

    std::call_once的作用是很简单的, 就是保证函数或者一些代码段在并发或者多线程的情况下,始终只会被执行一次.比如一些init函数,多次调用可能导致各种奇怪问题. 给个例子: #includ ...