这题如果构建失败指针的话,实现起来很麻烦!因为你要先要枚举枚举方向,然后再枚举起始点的坐标,很麻烦的样子……可以用点时间上做点牺牲,枚举每个顶点然后再向8个方向匹配,就不用构建失败指针了
#include<iostream>
#include<cstdlib>
#include<stdio.h>
using namespace std;
struct trie
{
trie* next[26];
int dex;
trie()
{
for(int i=0;i<26;i++)
next[i]=0;
dex=-1;
}
}root;
struct node
{
int x,y;
char c;
}wi[1010];
char st[1010][1010];
int dx[8]={-1,-1,0,1,1,1,0,-1};
int dy[8]={0,1,1,1,0,-1,-1,-1};
char dr[8]={'A','B','C','D','E','F','G','H'};
int n,m;
int ismap(int pi,int pj)
{
if(pi>=0&&pi<n&&pj>=0&&pj<m)
return 1;
return 0;
}
void insert(char* s,int num)
{
trie* p=&root;
int k=0;
while(s[k])
{
int index=s[k]-'A';
if(!p->next[index])
p->next[index]=new trie();
p=p->next[index];
k++;
}
p->dex=num;//标记每个要查找的单词
}
void find(int pi,int pj,int k)
{
trie* p=&root;
int l,r;
l=pi,r=pj;
while(ismap(pi,pj))
{
int index=st[pi][pj]-'A';
if(!p->next[index]) break;
p=p->next[index];
if(p->dex!=-1)
{
if(wi[p->dex].x==-1)
{
wi[p->dex].x=l;wi[p->dex].y=r;
wi[p->dex].c=dr[k];
}
}
pi+=dx[k];pj+=dy[k];
}
}
int main()
{
int w;
char str[1010];
int flag=0;
while(scanf("%d%d%d",&n,&m,&w)!=EOF)
{
if(flag)cout<<endl;
flag=1;
for(int i=0;i<n;i++)
scanf("%s",st[i]);
for(int i=1;i<=w;i++)
{
scanf("%s",str);
wi[i].x=-1;wi[i].y=-1;
insert(str,i);
}
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
for(int k=0;k<8;k++)
{
find(i,j,k);
}
}
for(int i=1;i<=w;i++)
cout<<wi[i].x<<" "<<wi[i].y<<" "<<wi[i].c<<endl;
}
return 0;
}
/*
3 5 2
HHHHH
HMYCH
HHHHH
MYC
YC
*/
我自己写了个要构建失败指针版的,不知道为什么就是wa,自己想的数据都过了,无语了,以后有时间在看看吧!
wa代码:
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define mm(a,what) sizeof(a,what,sizeof(a))
#define ff(i,a) for(int i=0;i<a;i++)
const int NODE=100010;
int chd[NODE][26],word[NODE],fail[NODE],sz,height[NODE];
void ins(char *s,int val)
{
int p=0,cnt=0;
for(;*s; s++)
{
int id=*s-'A';
//cout<<chd[p][id]<<" ";
if(!chd[p][id])
{
//memset(chd[sz],0,sizeof(sz));
for(int i=0;i<26;i++) chd[sz][i]=0;
word[sz]=0;
chd[p][id]=sz++;
}
p=chd[p][id];
height[p]=++cnt;
// cout<<p<<" ";
}
word[p]=val;
}
int Que[NODE];
void ac()
{
int *s=Que,*e=Que;
ff(i,26) if(chd[0][i])
{
*e++=chd[0][i];
fail[chd[0][i]]=0;
}
while(s!=e)
{
int p=*s++;
// cout<<p<<endl;
ff(i,26) if(chd[p][i])
{
*e++=chd[p][i];
fail[chd[p][i]]=chd[fail[p]][i];
}
else
chd[p][i]=chd[fail[p]][i];;
}
}
char map[1010][1010],R,L,Q;
int x[1010],y[1010],dir[1010];
int dirction[][2]= {{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
void search(int sx,int sy,int di)
{
int p=0;
//cout<<dirction[di][0]<<" "<<dirction[di][1]<<endl;
while(sx>=0&&sx<R&&sy>=0&&sy<L)
{
int id=map[sx][sy]-'A';
p=chd[p][id];
for(int tmp=p; tmp>0; tmp=fail[tmp])
if(word[tmp]!=0&&dir[word[tmp]]==-1)
{
x[word[tmp]]=sx-dirction[di][0]*(height[tmp]-1);
y[word[tmp]]=sy-dirction[di][1]*(height[tmp]-1);
dir[word[tmp]]=di;
//word[tmp]=-1;
}
sx+=dirction[di][0];
sy+=dirction[di][1];
}
}
char txt[3010];
int main()
{
while(scanf("%d%d%d",&R,&L,&Q)==3)
{
for(int i=0; i<R; i++)
scanf("%s",map[i]);
sz=1;
for(int i=0;i<26;i++) chd[0][i]=0;
for(int i=0; i<Q; i++)
{
scanf("%s",txt);
ins(txt,i+1);
}
ac();
memset(dir,-1,sizeof(dir));
for(int i=0; i<R; i++)
for(int k=0; k<8; k++)
{
search(i,0,k);
search(i,L-1,k);
}
for(int i=0; i<L; i++)
for(int k=0; k<8; k++)
{
search(0,i,k);
search(R-1,i,k);
}
for(int i=1; i<=Q; i++)
printf("%d %d %c\n",x[i],y[i],(char)(dir[i]+'A'));
}
return 0;
}
/*
3 5 4
HHXPHH
HMYCH
HHYHH
XP
PX
YX
HX
*/