最直观的想法是8*(n*n)*n*n暴力
由于在表里面要朝8个方向走,不能在上面建自动机,所以要在pattern建自动机
建好后,在原表上朝8个方向走遍历整个表,这时候复杂度是8*n*n
比较慢,但觉得比较直观
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define sigma_size 26
#define N 1010
struct Node
{
int idx;
Node *fail;
Node* nxt[sigma_size];
Node()
{
idx=0;fail=NULL;
memset(nxt,NULL,sizeof(nxt));
}
};
void _insert(char *s,Node *root,int idx)
{
for(int i=0;s[i]!='\0';++i)
{
if(root->nxt[s[i]-'A']==NULL)
root->nxt[s[i]-'A']=new Node();
root=root->nxt[s[i]-'A'];
}
root->idx=idx;
}
Node*q[1001000];
void getfail(Node *root)
{
int head=0,tail=0;
q[tail++]=root;
root->fail=NULL;
while(head<tail)
{
Node *u=q[head++];
for(int i=0;i<sigma_size;++i)
if(u->nxt[i])
{
if(u==root)
u->nxt[i]->fail=root;
else
{
Node *p=u->fail;
while(p!=NULL&&p->nxt[i]==NULL) p=p->fail;
u->nxt[i]->fail= p==NULL?root:p->nxt[i];
}
q[tail++]=u->nxt[i];
}
}
}
int dir[8][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
int ansx[N],ansy[N],ansz[N];
char mat[N][N],temp[N];
char T[N][N];
int L,C,W;
Node *root;
void dfs(int row,int col,int d,Node *u)
{
//if(u->idx==1||u->idx==2)
//cout<<'d';
if(u->idx)
{
/*ansx[u->idx]=row;
ansy[u->idx]=col;
ansz[u->idx]=d;*/
Node *p=u;
while(p!=NULL)
{
if(p->idx)
{
ansx[p->idx]=row;
ansy[p->idx]=col;
ansz[p->idx]=d;
}
p=p->fail;
}
}
if(row>=0&&row<L&&col>=0&&col<C);
else return;
if(u->nxt[mat[row][col]-'A'])
dfs(row+dir[d][0],col+dir[d][1],d,u->nxt[mat[row][col]-'A']);
else {
if(u==root)
dfs(row+dir[d][0],col+dir[d][1],d,u);
else dfs(row,col,d,u->fail);
}
}
int main ()
{
while(scanf("%d%d%d",&L,&C,&W)!=EOF)
{
for(int i=0;i<L;++i)
scanf("%s",mat[i]);
root=new Node();
for(int i=1;i<=W;++i)
{
scanf("%s",T[i]);
_insert(T[i],root,i);
}
getfail(root);
for(int i=0;i<L;++i)
for(int j=0;j<C;++j)
if(i==0||i==L-1||j==0||j==C-1)
{
for(int d=0;d<8;++d)
dfs(i,j,d,root);
}
for(int i=1;i<=W;++i)
{
int rev=(ansz[i]+4)%8;
int tt=strlen(T[i]);
for(int j=1;j<=tt;++j)
{
ansx[i]+=dir[rev][0];
ansy[i]+=dir[rev][1];
}
ansz[i]+='A';
printf("%d %d %c\n",ansx[i],ansy[i],ansz[i]);
}
}
return 0;
}