• 【uva11019-Matrix Matcher】AC自动机+优化+记录


    http://acm.hust.edu.cn/vjudge/problem/33057

    题意:在二维文本串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<queue>
      6 #include<vector>
      7 using namespace std;
      8 
      9 int n,m,num,ans;
     10 int ct[1100][1100],nt[110];
     11 char s[1100][1100],ss[1100][1100];
     12 struct node{
     13     int son[30];
     14     int fail,ed;
     15 }a[110*110];
     16 queue<int> q;
     17 
     18 void clear(int x)
     19 {
     20     a[x].fail=a[x].ed=0;
     21     memset(a[x].son,0,sizeof(a[x].son));
     22 }
     23 
     24 void trie(char *c,int id)
     25 {
     26     int l=strlen(c);
     27     int x=0;
     28     for(int i=0;i<l;i++)
     29     {
     30         int t=c[i]-'a'+1;
     31         if(!a[x].son[t])
     32         {
     33             num++;
     34             clear(num);
     35             a[x].son[t]=num;
     36         }
     37         x=a[x].son[t];
     38     }
     39     if(!a[x].ed) a[x].ed=id;
     40 }
     41 
     42 void buildAC()
     43 {
     44     while(!q.empty()) q.pop();
     45     for(int i=1;i<=26;i++) 
     46         if(a[0].son[i]) q.push(a[0].son[i]);
     47     while(!q.empty())
     48     {
     49         int x=q.front();q.pop();
     50         int fail=a[x].fail;
     51         for(int i=1;i<=26;i++)
     52         {
     53             int y=a[x].son[i];
     54             if(y)
     55             {
     56                 a[y].fail=a[fail].son[i];
     57                 q.push(y);
     58             }
     59             else a[x].son[i]=a[fail].son[i];
     60         }
     61     }
     62 }
     63 
     64 void find(char *c,int id)
     65 {
     66     int l=strlen(c);
     67     int x=0;
     68     for(int i=0;i<l;i++)
     69     {
     70         int t=c[i]-'a'+1;
     71         if(!a[x].son[t]) x=0;
     72         x=a[x].son[t];
     73         int x0=id,y0=(i+1)-m+1;
     74         int p=a[x].ed;
     75         while(p)
     76         {
     77             int xx=x0-p+1,yy=y0;
     78             if(xx>=1 && yy>=1)//注意!!没有就WA!!
     79             {
     80                 ct[xx][yy]++;
     81                 if(ct[xx][yy]>=n) ans++;        
     82             }
     83             p=nt[p];
     84         }
     85     }
     86 }
     87 
     88 int main()
     89 {
     90     freopen("a.in","r",stdin);
     91     freopen("a.out","w",stdout);
     92     int T;
     93     scanf("%d",&T);
     94     while(T--)
     95     {
     96         num=ans=0;
     97         clear(0);
     98         memset(ct,0,sizeof(ct));
     99         memset(nt,0,sizeof(nt));//用nt数组(next)优化,不然就TLE。
    100         int x,y;
    101         scanf("%d%d",&x,&y);
    102         for(int i=1;i<=x;i++)
    103         {
    104             scanf("%s",ss[i]);
    105         }
    106         scanf("%d%d",&n,&m);
    107         for(int i=1;i<=n;i++)
    108         {
    109             scanf("%s",s[i]);
    110             trie(s[i],i);
    111         }
    112         for(int i=1;i<=n;i++)
    113             for(int j=i+1;j<=n;j++)
    114             {
    115                 if(strcmp(s[i],s[j])==0) {nt[i]=j;break;}
    116             }
    117         buildAC();
    118         for(int i=1;i<=x;i++) find(ss[i],i);
    119         printf("%d
    ",ans);
    120     }
    121     return 0;
    122 }
  • 相关阅读:
    scroll
    "严格模式" use strict 详解
    thymeleaf 模板布局
    前端性能优化
    原生的强大DOM选择器querySelector
    thymeleaf 基本语法
    读书笔记JavaScript中的全局对象
    JavaScript中getBoundingClientRect()方法详解
    JavaScript 中的内存泄漏
    jsonp 跨域原理详解
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/5686442.html
Copyright © 2020-2023  润新知