uva11019矩阵匹配器D316

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<cstdlib>
 6 #include<algorithm>
 7 #include<queue>
 8 using namespace std;
 9 int c[1002][1002];
10 int mx,nx,m,n;
11 struct AC
12 {
13     int ch[10002][28];
14     int cnt;
15     int value[10002],fail[10002],last[10002],next[10001];
16     AC(){memset(next,0,sizeof(next));memset(ch,0,sizeof(ch));cnt=0;memset(value,0,sizeof(value));memset(fail,0,sizeof(fail));memset(last,0,sizeof(last));}
17     void trie(char *s,int v)
18     {
19         int now=0,len=strlen(s);
20         for(int i=0;i<len;i++)
21         {
22             if(!ch[now][s[i]-'a']) ch[now][s[i]-'a']=++cnt;
23             now=ch[now][s[i]-'a'];
24         }
25         if(value[now])
26         {
27             next[v]=value[now];
28         }
29         value[now]=v;
30     }
31     void getfail()
32     {
33         queue<int>q;
34         for(int i=0;i<26;i++){if(ch[0][i]) q.push(ch[0][i]);}
35         while(!q.empty())
36         {
37             int now=q.front();q.pop();
38             for(int i=0;i<26;i++)
39             {
40                 int u=ch[now][i];
41                 if(!u){ch[now][i]=ch[fail[now]][i];continue;}
42                 int t=fail[now];
43                 while(t&&!ch[t][i]) t=fail[t];
44                 fail[u]=ch[t][i];
45                 last[u]=value[fail[u]]?fail[u]:last[fail[u]];
46                 q.push(u);
47             }
48         }
49     }
50     void add(int now,int h,int i)
51     {
52         if(now)
53         {
54             if(h-value[now]+1>=0) c[h-value[now]+1][i]++;
55             int t=value[now];
56             while(next[t])
57             {
58                 t=next[t];
59                 if(h-t+1>=0) c[h-t+1][i]++;
60             }
61             add(last[now],h,i);
62         }
63     }
64     void find(char *s,int h)
65     {
66         int len=strlen(s);
67         int now=0;
68         for(int i=0;i<len;i++)
69         {
70             now=ch[now][s[i]-'a'];
71             if(value[now]) add(now,h,i);
72             else add(last[now],h,i);
73         }
74     }
75 }ac;
76 int main()
77 {
78     int ans=0;
79     char chh[1001][1001];
80     scanf("%d%d",&mx,&nx);
81     for(int i=0;i<mx;i++)scanf("%s",chh[i]);
82     scanf("%d%d",&m,&n);
83     for(int i=1;i<=m;i++)
84     {
85         char temp[1001];
86         scanf("%s",temp);
87         ac.trie(temp,i);
88     }
89     ac.getfail();
90     for(int i=0;i<mx;i++) ac.find(chh[i],i);
91     for(int i=0;i<mx;i++)
92         for(int j=0;j<nx;j++) if(c[i][j]==m) ans++;
93     cout<<ans;
94 }
View Code

 

 

矩阵匹配器D316
难度级别:C; 运行时间限制:1500ms; 运行空间限制:262144KB; 代码长度限制:2000000B
试题描述
给你一个sx*sy的小矩阵和一个mx*my的大矩阵,请你求出小矩阵在大矩阵中出现的次数
输入
第一行两个正整数mx,my
接下来跟一个mx行my列的大矩阵
又接下来两个正整数sx,sy
再接下来跟一个sx行sy列的小矩阵
输出
小矩阵在大矩阵中出现的次数
输入示例
3 3
abc
bca
caa
2 2
bc
ca
输出示例
2
其他说明
数据范围:sx≤mx≤1000,sy≤my≤1000 sx,sy≤100
posted @ 2017-02-27 23:11  wls001  阅读(179)  评论(0编辑  收藏  举报