Uva 11019 Matrix Matcher

来源:互联网 发布:c语言二分法求方程例题 编辑:程序博客网 时间:2024/04/25 12:47
看起来像是二维的AC自动机。。。坑了我2天。。。。0.000秒WA怎么都过不了。。。

找AC的程序对拍也找不到错误,最后直接交AC的程序也是WA。。。估计是数据出问题了抓狂

# ProblemVerdictLanguageRun TimeSubmission Date127262 7711019Matrix MatcherWrong answerC++0.0002013-11-25 03:23:361272626111019Matrix MatcherWrong answerC++0.0002013-11-25 03:16:561272620011019Matrix MatcherWrong answerC++0.0002013-11-25 03:02:231272614811019Matrix MatcherWrong answerC++0.0002013-11-25 02:25:171272373811019Matrix MatcherWrong answerC++0.0002013-11-24 14:31:031272367311019Matrix MatcherWrong answerC++0.0002013-11-24 14:20:161272322411019Matrix MatcherWrong answerC++0.0002013-11-24 12:43:50

题意:给出一个n*m的字符矩阵T,你的任务是找出给定的x*y的字符矩阵P在T中出现了多少次.

分析:要想整个矩阵匹配,至少各行都得匹配。所以先把P的每行看做一个模式串构造出AC自动机,然后在T中的各行逐一匹配,找到P中每一行的所有匹配点。

只要在匹配时做一些附加操作,就可以把匹配出来的单一的行拼成矩形。用一个d[r][c]表示T中一(r,c)为右上角,与P等大的矩形中有多少个完整的行和P对应位置的行完全相同.当P的第i行出现在T的第r行,起始列编号为c时,意味着d[r-i][c]应当加1.所有匹配结束后,d[r][c]=X的那些就是一个二维匹配点.

注意:模式串有可能相同.

Matrix Matcher
Time Limit: 3000MSMemory Limit: Unknown64bit IO Format: %lld & %llu

[Submit]   [Go Back]   [Status]  

Description

Download as PDF

Problem H
Matrix Matcher
Input: 
Standard Input

Output: Standard Output

 

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                               Output for Sample Input

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

0

2

 


                                                  




                                   


Problem Setter: Rujia Liu, EPS

Special Thanks: Wenbin Tang

 

Warming: The judge input file size is about 7 MB. So please make sure that you use a fast IO function (eg. scanf()) to read input.

 

#include <iostream>#include <cstring>#include <cstdio>#include <queue>#include <vector>using namespace std;const int maxn=11000;int m,n,x,y;char T[1100][1100],P[110][110];int chd[maxn][26],sz,val[maxn],last[maxn],f[maxn];int ct[1100][1100];vector<int> next[maxn];int init(){    sz=1;    memset(chd[0],0,sizeof(chd[0]));    memset(ct,0,sizeof(ct));    memset(val,0,sizeof(val));    memset(last,0,sizeof(last));    memset(f,0,sizeof(f));    for(int i=0;i<10000;i++) next[i].clear();}int insert(char *p,int i){    int u=0;    for(;*p;p++)    {        if(!chd[u][*p-'a'])        {            memset(chd[sz],0,sizeof(chd[sz]));            chd[u][*p-'a']=sz++;        }        u=chd[u][*p-'a'];    }    val[u]=i;    next[u].push_back(i);}int getFail(){    queue<int> q;    f[0]=0;    for(int c=0;c<26;c++)    {        int u=chd[0][c];        if(u)        {            f[u]=last[u]=0;            q.push(u);        }    }    while(!q.empty())    {        int r=q.front(); q.pop();        for(int c=0;c<26;c++)        {            int u=chd[r][c];            if(!u)            {                chd[r][c]=chd[f[r]][c];                continue;            }            q.push(u);            int v=f[r];            while(v&&!chd[v][c]) v=f[v];            f[u]=chd[v][c];            last[u]=val[f[u]]?f[u]:last[f[u]];        }    }}void solve(int u,int line,int lie){    if(val[u])    {        int t=next[u].size();        for(int i=0;i<t;i++)        {            if(line-next[u][i]+1>=0)                ct[line-next[u][i]+1][lie-y+1]++;        }        solve(last[u],line,lie);    }}void find(char* T,int L){    int j=0;    for(int i=0;i<m;i++)    {        int c=T[i]-'a';        j=chd[j][c];        if(val[j]) solve(j,L,i);        else if(last[j]) solve(last[j],L,i);    }}int main(){    int tt;    scanf("%d",&tt);    while(tt--)    {        scanf("%d%d",&n,&m);        for(int i=0;i<n;i++) scanf("%s",T[i]);        init();        scanf("%d%d",&x,&y);        for(int i=1;i<=x;i++)        {            scanf("%s",P[i]);            insert(P[i],i);        }        getFail();        for(int i=0;i<n;i++)        {            find(T[i],i);        }        int ans=0;        for(int i=0;i<n;i++)        {            for(int j=0;j<m;j++)            {            //    cout<<ct[i][j]<<" ";                if(ct[i][j]==x) ans++;            }        //    cout<<endl;        }        printf("%d\n",ans);    }    return 0;}







原创粉丝点击