AC自动机
#include <iostream> //poj 1204 Word Puzzles
using namespace std ;
struct Node
{
Node *next[26];
Node *fail;
int des; //标记要查找的单词最后一个字母出现的地方
Node():des(-1),fail(NULL)
{
memset(next,NULL,sizeof(next));
}
int heigh;
}*root,*q[100000];
char table[1005][1005],ch[5000]; //table[1005][1005]为单词表,ch[5000]为要查找的单词
int res[1005][3],found[1005]; //res[i]记录要查找的第i个单词的结果
int L,C,W,count,flag,cnt=1;
int head,tail;
void insert(int rank)
{
Node *p=root;
int index,i;
for(i=0;ch[i];++i)
{
index=ch[i]-'A';
if(p->next[index]==NULL)
{
p->next[index]=new Node(); //申请空间
}
p=p->next[index];
p->heigh=i+1;
}
p->des=rank;
}
void build_ac_automation()
{
head=tail=0;
root->fail=NULL;
q[head++]=root;
while(head!=tail)
{
Node *temp=q[tail++];
Node *p=NULL;
for(int i=0;i<26;++i)
{
if(temp->next[i]!=NULL)
{
if(temp==root)
temp->next[i]->fail=root;
else
{
p=temp->fail;
while(p!=NULL)
{
if(p->next[i]!=NULL)
{
temp->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL)
temp->next[i]->fail=root;
}
q[head++]=temp->next[i];
}
}
}
}
void search(int i,int j,int way)
{
Node *p=root;
int index;
while(i>=0&&i<L&&j>=0&&j<C)
{
index=table[i][j]-'A';
while(p->next[index]==NULL&&p!=root)
p=p->fail;
p=p->next[index];
p=(p==NULL)?root:p;
Node *temp=p;
while(temp!=root&&temp->des!=-1&&!found[temp->des])
{
found[temp->des]=1;
count++;
int start_i=i,start_j=j,h=temp->heigh-1;
switch (way)
{
case 1:
start_i+=h;break;
case 2:
start_i+=h;start_j-=h;break;
case 3:
start_j-=h;break;
case 4:
start_i-=h;start_j-=h;break;
case 5:
start_i-=h;break;
case 6:
start_i-=h;start_j+=h;break;
case 7:
start_j+=h;break;
case 8:
start_i+=h;start_j+=h;break;
default:
break;
}
res[temp->des][0]=start_i;
res[temp->des][1]=start_j;
res[temp->des][2]=way;
temp=temp->fail;
}
if(count==W)
{
flag=1;break; //表示查找完毕
}
switch(way) //1 代表正北,顺时针依次是 东北2,正东3,东南4,正南5,西南6,正西7,西北8。
{
case 1:
i-=1;break;
case 2:
i-=1;j+=1;break;
case 3:
j+=1;break;
case 4:
i+=1;j+=1;break;
case 5:
i+=1;break;
case 6:
i+=1;j-=1;break;
case 7:
j-=1;break;
case 8:
i-=1;j-=1;break;
default:break;
}
}
}
int main()
{
root=new Node(); //对root初始化
scanf("%d%d%d",&L,&C,&W);
for(int i=0;i<L;++i)
{
scanf("%s",table[i]);
}
for(int i=0;i<W;++i)
{
scanf("%s",ch);
insert(i);
}
build_ac_automation();
//for(int i=0;i<L&&!flag;++i) //tle,因为重复计算了很多次
//{
// for (int j=0;j<C&&!flag;++j)
// {
// for(int k=1;k<=8&&!flag;++k)
// {
// search(i,j,k);
// }
// }
//}
//列举出每一个方向
for(int i=0;i<L&&!flag;++i)
{
search(i,0,3);
search(i,C-1,7);
search(i,0,2);
search(i,C-1,6);
search(i,0,4);
search(i,C-1,8);
}
for(int j=0;j<C&&!flag;++j)
{
search(0,j,5);
search(L-1,j,1);
search(L-1,j,2);
search(0,j,6);
search(0,j,4);
search(L-1,j,8);
}
for(int i=0;i<W;++i)
printf("%d %d %c\n",res[i][0],res[i][1],(char)(res[i][2]+64));
return 0 ;
}
//http://www.cppblog.com/mythit/archive/2009/04/21/80633.html