题意简化,给你一个大矩阵和一个小矩阵,求小矩阵在大矩阵中出现了多少次,矩阵都不得旋转
这个题就是字符串匹配的二维版,然而不像数据结构,它的二维版并不复杂只是一行行拆开处理,但复杂度十分优越,几乎等于读入时间(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&#