美文网首页
Uva(11019)(Matrix Matcher)

Uva(11019)(Matrix Matcher)

作者: kimoyami | 来源:发表于2018-09-05 10:51 被阅读17次

链接:https://vjudge.net/problem/UVA-11019
思路:我们需要改造一下就可以变成一个自动机的题目,我们把需要查找的矩阵按行拆成母串,然后构成一个trie图,用val记录他在原矩阵中的行数,然后将大的那个矩阵拆分成行依次进行匹配,当匹配成功就将对应的矩阵左上角顶点的值++,当某一个点的值等于小矩阵的行数的时候,就说明找到了一个矩阵。
注意事项:做自动机时一定要考虑到母串可能重叠覆盖的问题,对于本题可以将val改造成一个vector,记录每个的对应行数,还有一个就是注意内存问题,自动机的题很容易超内存!
代码:

#include<bits/stdc++.h>
using namespace std;

const int maxnode = 1e6+10;
const int sigma_size = 26;
int t,n,m,x,y;
char str1[1010][1010];
char str2[1010][1010];

struct AC{
    int ch[maxnode][sigma_size];
    int num[1010][1010];
    int sz;
    vector<int> val[maxnode];
    int f[maxnode];

    void init(){
        sz = 1;
        memset(ch[0],0,sizeof(ch[0]));
        memset(num,0,sizeof(num));
        val[0].clear();
    }

    inline int idx(char c){
        return c-'a';
    }

    void insert(char *s,int r){
        int u=0;
        int n = strlen(s);
        for(int i=0;i<n;i++){
            int c = idx(s[i]);
            if(!ch[u][c]){
                memset(ch[sz],0,sizeof(ch[sz]));
                val[sz].clear();
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
        val[u].push_back(r);
    }

    void getfail(){
        queue<int> q;
        f[0] = 0;
        for(int c=0;c<sigma_size;c++){
            int u = ch[0][c];
            if(u){
                f[u] = 0;
                q.push(u);
            }
        }
        while(!q.empty()){
            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];
            }
        }
    }

    void print(int i,int j,int k){
      //  printf("%d %d\n",i,j);
        if(i-k+1>0&&j-y+1>0)
        num[i-k+1][j-y+1]++;//对应的矩阵的左上角的顶点值++
    }

    void find(char *s,int r){
        int n = strlen(s);
        int j = 0;
        for(int i=0;i<n;i++){
            int c = idx(s[i]);
            j = ch[j][c];
            if(val[j].size()){
                for(int p=0;p<val[j].size();p++)
                print(r,i+1,val[j][p]);
            }
        }
    }
}solver;

int main(){
    scanf("%d",&t);
    while(t--){
        solver.init();
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%s",str1[i]);
        }
        scanf("%d%d",&x,&y);
        for(int i=1;i<=x;i++){
            scanf("%s",str2[i]);
            solver.insert(str2[i],i);
        }
        solver.getfail();
        for(int i=1;i<=n;i++){
            solver.find(str1[i],i);
        }
        int  ans = 0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(solver.num[i][j]==x)ans++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

相关文章

网友评论

      本文标题:Uva(11019)(Matrix Matcher)

      本文链接:https://www.haomeiwen.com/subject/nbaowftx.html