题意:给个L*C的字符串矩阵,W个询问,对每个询问输出这个串第一次出现的位置及方向,共有8个方向,用A~H表示
思路:其实就是普通的AC自动机,但由于有八个方向,所以要把各种方向的可能性都给试一遍。注意,由于要记录开始字符串,所以在构造tire树的时候就应该把那些字符串倒过来构造,切记。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
char s[1005][1005];
char tp[1005];
int ans[1005][3],l,c,w;
struct node
{
node *next[26],*fail;
int fg;
node()
{
fail=NULL;
for(int i=0;i<26;i++)
next[i]=NULL;
fg=0;
}
}*q[500000],*root;
int dir[8][3]={{0,-1},{1,-1},{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1}};
void build_tire(node *p,int id)
{
int t=strlen(tp);
for(int i=t-1;i>=0;i--)
{
if(p->next[tp[i]-'A']==NULL)
{
p->next[tp[i]-'A']=new node();
}
p=p->next[tp[i]-'A'];
}
p->fg=id;
}
void make_ac(node *p)
{
node *temp,*temp1;
int head,tail;
head=tail=0;
q[tail++]=p;
while(head!=tail)
{
temp=q[--tail];
for(int i=0;i<26;i++)
{
if(temp->next[i]!=NULL)
{
if(temp==root) temp->next[i]->fail=root;
else
{
temp1=temp->fail;
while(temp1!=NULL)
{
if(temp1->next[i]!=NULL)
{
temp->next[i]->fail=temp1->next[i];
break;
}
temp1=temp1->fail;
}
if(temp1==NULL) temp->next[i]->fail=root;
}
q[tail++]=temp->next[i];
}
}
}
}
void query(int x,int y,int id,int id1)
{
node *p=root,*temp;
while(x>=0&&y>=0&&x<l&&y<c)
{
int t=s[x][y]-'A';
while(p->next[t]==NULL&&p!=root) p=p->fail;
p=p->next[t];
if(p==NULL) p=root;
temp=p;
while(temp!=root)
{
if(temp->fg)
{
ans[temp->fg][0]=x;
ans[temp->fg][1]=y;
ans[temp->fg][2]=id1;
}
temp=temp->fail;
}
x+=dir[id][1];
y+=dir[id][0];
}
}
void del(node *p)
{
if(p==NULL)return ;
for(int i=0;i<26;i++)del(p->next[i]);
delete p;
}
int main()
{
//freopen("t.txt","r",stdin);
while(scanf("%d%d%d",&l,&c,&w)!=EOF)
{
memset(ans,-1,sizeof(ans));
root= new node();
for(int i=0;i<l;i++) {scanf("%s",s[i]);}
for(int i=1;i<=w;i++)
{
scanf("%s",tp);
build_tire(root,i);
}
make_ac(root);
for(int i=0;i<l;i++)
{
query(i,0,1,5);
query(i,0,2,6);
query(i,0,3,7);
query(i,c-1,7,3);
query(i,c-1,6,2);
query(i,c-1,5,1);
}
for(int j=0;j<c;j++)
{
query(l-1,j,1,5);
query(l-1,j,0,4);
query(l-1,j,7,3);
query(0,j,3,7);
query(0,j,4,0);
query(0,j,5,1);
}
for(int i=1;i<=w;i++)
{
char t=ans[i][2]+'A';
printf("%d %d %c\n",ans[i][0],ans[i][1],t);
}
del(root);
}
return 0;
}