zoukankan      html  css  js  c++  java
  • UVA11019 Matrix Matcher (AC自动机)

    二维的矩阵匹配,把模式矩阵按列拆开构造AC自动机,记录行号(为了缩点判断)。

    把T矩阵按行匹配,一旦匹配成功,在假想的子矩阵左上角位置加一。最后统计总数。

    因为所有模式串长度一样,不用维护last数组。

    模式串可能有重复,结点要用vector来存。

    HASH出奇迹,快得不行。。。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1001,maxm = 101;
    char Text[maxn][maxn], pattern[maxm];
    const int maxnds = maxm*maxm, sigma_size = 26;
    int nds;
    int ch[maxnds][sigma_size];
    int f[maxnds];
    vector<int> val[maxnds];
    
    void bfs()
    {
        f[0] = 0; 
        queue<int> q;
        for(int c = 0; c < sigma_size; c++){
            int u = ch[0][c];
            if(u){ q.push(u); f[u] = 0;} 
        }
        while(q.size()){
            int r = q.front(); q.pop();
            for(int c = 0; c < sigma_size; c++){
                int u = ch[r][c];
                if(!u) { ch[r][c] = ch[f[r]][c]; continue; }
                q.push(u);
                int v = f[r];
                while(v && !ch[v][c]) v = f[v];
                f[u] = ch[v][c];
            }
        }
    }
    
    #define idx(x) x-'a';
    void add(char *s,int i)
    {
        int n = strlen(s), u = 0;
        for(int i = 0; i < n; i++){
            int c = idx(s[i]);
            if(!ch[u][c]){
                u = ch[u][c] = nds++;
                memset(ch[u],0,sizeof(ch[u]));
                val[u].clear();
            }else u = ch[u][c];
        }
        val[u].push_back(i);
    }
    
    void init()
    {
        nds = 1;
        memset(ch[0],0,sizeof(ch[0]));
        val[0].clear();
    }
    
    int cnt[maxn][maxn];
    int N,M;
    int X,Y;
    
    void cal(int i,int j)
    {
        if(i>=0) cnt[i][j]++;
    }
    
    void Find(char *T,int R)
    {
        int n = strlen(T), u = 0;
        for(int i = 0; i < n; i++){
            int c = idx(T[i]);
            u = ch[u][c];
            if(val[u].size() ){
                for(auto it:val[u]){
                    cal(R-it+1,i-Y+1);
                }
            }
        }
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        int T;cin>>T;
        while(T--){
            init();
            scanf("%d%d",&N,&M);
            for(int i = 0; i < N; i++){
                scanf("%s",Text[i]);
            }
            scanf("%d%d",&X,&Y);
            for(int i = 1; i <= X; i++){
                scanf("%s",pattern);
                add(pattern,i);
            }
            bfs();
            for(int i = 0; i < N; i++){
                Find(Text[i],i);
            }
            int ans = 0;
            for(int i = 0; i < N; i++){
                for(int j = 0; j < M; j++){
                    if(cnt[i][j]){
                        if(cnt[i][j] == X) ans++;
                        cnt[i][j] = 0;
                    }
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    phone8 inapp purchasing
    Delegate,Action,Func,匿名方法,匿名委托,事件
    get a full screen popup to work on WP8
    as3.0动态文本大全
    actionScript 3 殿堂之路 第四章 学习收获
    java中的switch case
    Silverlight的DataGrid导出文档
    ArcGIS教程大全
    同步异步请求区别
    XML操作,XPath语法
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4798348.html
Copyright © 2011-2022 走看看