【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\n",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 }
2016-07-12 15:37:53