UVA11019 矩阵匹配器

题意简化,给你一个大矩阵和一个小矩阵,求小矩阵在大矩阵中出现了多少次,矩阵都不得旋转


这个题就是字符串匹配的二维版,然而不像数据结构,它的二维版并不复杂只是一行行拆开处理,但复杂度十分优越,几乎等于读入时间(vjudge上跑了0ms)

首先将小矩阵的每一行分开看,这样小矩阵就成了多个模板串,建个AC自动机。再用大矩阵的每一行去AC自动机里找匹配,例如大矩阵第i行的第j位与第k个模板串(小矩阵第k行)匹配上了,那么(i-(k-1),j)就是一个满足一行相等的右上角。开个C数组保存一个点作为右上角的小矩阵与目标小矩阵有几行一样,这样C[i][j]=x的点就是合法点。统计一下合法点的个数,即为答案

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define MAXN (1010)
using namespace std;
int A[MAXN][MAXN],B[MAXN][MAXN],n,m,x,y,son[MAXN*MAXN][151];
int Size,C[MAXN][MAXN],f[MAXN*MAXN],h[MAXN*MAXN],m1;
char S[MAXN];
struct edge{
	int next,to;
	void Add(int Next,int To){
		next=Next; to=To;
	}
}q[MAXN*MAXN];
void addedge(int x,int y){
	q[++m1].Add(h[x],y); h[x]=m1;
}
void Build(int Num){
	int rt=0,i,d;
	for (i=1;i<=y;i++){
		int d=B[Num][i];
		if (!son[rt][d]) son[rt][d]=++Size;
		rt=son[rt][d];
	}
	addedge(rt,Num);
}
void Get_fail(){
	queue <int> Q;
	memset(f,0,sizeof(f));
	int i;
	for (i=0;i<150;i++)
		if (son[0][i])
			Q.push(son[0][i]);
	
	while (!Q.empty()){
		int x=Q.front(); Q.pop();
		for (i=0;i<=150;i++){
			if (!son[x][i]){
				son[x][i]=son[f[x]][i];
				continue;
			}
			Q.push(son[x][i]);
			int v=f[x],u=son[x][i];
			while (v&&!son[v][i]) v=f[v];
			f[u]=son[v][i];
		}
	}
}
void Find(int Num){
	int i,rt=0,j,y;
	for (i=1;i<=m;i++){
		int d=A[Num][i];
		rt=son[rt][d];
		for (j=h[rt];j;j=q[j].next){
			y=q[j].to;
			C[Num-(y-1)][i]++;
		}
	}
}
void Work(){
	scanf("%d %d",&n,&m);
	memset(A,0,sizeof(A));
	memset(B,0,sizeof(B));
	memset(son,0,sizeof(son));
	memset(h,0,sizeof(h));
	memset(C,0,sizeof(C));
	memset(q,0,sizeof(q));
	Size=0; m1=0;
	
	int i,j;
	for (i=1;i<=n;i++){
		scanf("%s",S);
		for (j=1;j<=m;j++)
			A[i][j]=S[j-1];
	}
	scanf("%d %d",&x,&y);
	for (i=1;i<=x;i++){
		scanf("%s",S);
		for (j=1;j<=y;j++)
			B[i][j]=S[j-1];
		Build(i);
	}
	Get_fail();
	for (i=1;i<=n;i++)
		Find(i);
	
	int ans=0;
	for (i=1;i<=n;i++)
	  for (j=1;j<=m;j++)
	    if (C[i][j]==x) ans++;
	printf("%d\n",ans);
}
int main(){
	int T; cin>>T;
	while (T--) Work();
}

猜你喜欢

转载自blog.csdn.net/lerbon23james/article/details/79794894