• 【UVA11019】Matrix Matcher


    Description

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

    Input
    The first line contains a single integer t (t ≤ 15), the number of test cases.
    For each case, the first line contains two integers N and M (N, M ≤ 1000). The next N lines
    contain M characters each.
    The next line contains two integers X and Y (X, Y ≤ 100). The next X lines contain Y characters
    each.

    Output

    For each case, output a single integer in its own line, the number of occurrences.

    Sample Input

    2
    1 1
    x
    1 1
    y
    3 3
    abc
    bcd
    cde
    2 2
    bc
    cd


    Sample Output
    0
    2

    【题意】

      在二维文本串T中查找一个二维模板串P出现了多少次。

    【分析】

      拆分模板串P的每一行,建AC自动机。

      拆分文本串T的每一行,在自动机中与P匹配,ct[i][j]表示以点(i,j)为左上角、与P等大的矩形有多少个对应的行与P匹配。
      最后ct[i][j]==P的行数的i,j就是一个匹配点,ans++。
      

      注意:1.原本我在trie的叶子用动态数组维护了一个表示这一行是P的第几行的数组,但是超时了,后来看了LRJ的代码,改成了用一个nt[i]来表示重复的行的下一行,就A了。
      2.注意在ct[i][j]里加的时候判断i,j是否大于0.

    代码如下:

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<queue>
      7 using namespace std;
      8 #define Maxn 1010
      9 #define Maxl 110
     10 #define INF 0xfffffff
     11 
     12 int n,m,l,r;
     13 int ct[Maxn][Maxn],nt[Maxl];
     14 char s[Maxn][Maxn];
     15 char ss[Maxn];
     16 
     17 struct node
     18 {
     19     int fail,mark;
     20     int son[30];
     21 }t[Maxn*Maxn];int tot;
     22 
     23 void upd(int x)
     24 {
     25     t[x].mark=0;
     26     memset(t[x].son,0,sizeof(t[x].son));
     27 }
     28 
     29 void read_trie(int tk)
     30 {
     31     scanf("%s",s[0]+1);
     32     int len=strlen(s[0]+1);
     33     for(int i=1;i<=len;i++) ss[i]=s[0][len-i+1];
     34     int now=0;
     35     for(int i=1;i<=len;i++)
     36     {
     37         int ind=ss[i]-'a'+1;
     38         if(!t[now].son[ind]) 
     39         {
     40             t[now].son[ind]=++tot;
     41             upd(tot);
     42         }
     43         now=t[now].son[ind];
     44         if(i==len) 
     45         {
     46             if(t[now].mark) nt[tk]=t[now].mark;//我好搞笑
     47             t[now].mark=tk;
     48         }
     49     }
     50 }
     51 
     52 queue<int > q;
     53 void build_AC()
     54 {
     55     while(!q.empty()) q.pop();
     56     q.push(0);
     57     while(!q.empty())
     58     {
     59         int x=q.front();q.pop();
     60         for(int i=1;i<=26;i++) 
     61         {
     62             if(t[x].son[i])
     63             {
     64                 t[t[x].son[i]].fail=x?t[t[x].fail].son[i]:0;
     65                 q.push(t[x].son[i]);
     66             }
     67             else t[x].son[i]=t[t[x].fail].son[i];
     68         }
     69         if(t[t[x].fail].mark) t[x].mark=t[t[x].fail].mark;
     70     }
     71 }
     72 
     73 void add(int x,int y,int z)
     74 {
     75     if(x-z+1>=1) ct[x-z+1][y]++;
     76     if(nt[z]!=0) add(x,y,nt[z]);
     77 }
     78 
     79 void ffind()
     80 {
     81     int now;
     82     memset(ct,0,sizeof(ct));
     83     for(int i=1;i<=n;i++)
     84     {
     85         now=0;
     86         for(int j=m;j>=1;j--)
     87         {
     88             now=t[now].son[s[i][j]-'a'+1];
     89             if(t[now].mark) add(i,j,t[now].mark);
     90         }
     91     }
     92     int ans=0;
     93     for(int i=1;i<=n;i++)
     94      for(int j=1;j<=m;j++)
     95         if(ct[i][j]==l) ans++;
     96     printf("%d
    ",ans);
     97 }
     98 
     99 void init()
    100 {
    101     scanf("%d%d",&n,&m);
    102     for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
    103     tot=0;upd(0);
    104     scanf("%d%d",&l,&r);
    105     memset(nt,0,sizeof(nt));
    106     for(int i=1;i<=l;i++)
    107     {
    108         read_trie(i);
    109     }
    110     build_AC();
    111 }
    112 
    113 int main()
    114 {
    115     int T;
    116     scanf("%d",&T);
    117     while(T--)
    118     {
    119         init();
    120         ffind();
    121     }
    122     return 0;
    123 }
    [UVA11019]

    2016-07-12 15:37:53

  • 相关阅读:
    php防止用户输入进行跨站攻击的方式
    php中相关函数
    php运算符
    php中error_reporting
    php环境的安装
    LAMP环境介绍
    js的StringBuffer类
    一个带关闭按钮的Div窗口,很漂亮
    js  计算是今天多少周
    java 递归
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5663728.html
Copyright © 2020-2023  润新知