题目大意:给出一个字符矩阵,在给出r个单词,找出这些单词在矩阵中出现的坐标和方向
由于数据规模的关系,直接搜索肯定是不行滴,。借助TRIE数据结构可以过掉,具体思路:枚举矩阵中的每一个位置和每一个方向,如果从该方向搜下去的字符出现trie树中的话就继续往下,如果trie树中没有的话,就break掉
代码:写的还是蛮清楚的嘛
#include <iostream>
#include <cstring>
#define maxnode 500000
#define maxn 1020
using namespace std;
struct trie
{
int ch[maxnode][26];
int val[maxnode];
int sz;
int idx(char c)
{
return c-'A';
}
trie()
{
sz=1;
memset(ch[0],0,sizeof(ch[0]));
}
void insert(char *s,int v)
{
int u=0,n=strlen(s);
for(int i=0; i<n; i++)
{
int c=idx(s[i]);
if(!ch[u][c])
{
ch[u][c]=sz++;
memset(ch[sz],0,sizeof(ch[sz]));
}
u=ch[u][c];
}
val[u]=v;
}
int find(char *s)
{
int u=0,n=strlen(s);
for(int i=0; i<n; i++)
{
int c=idx(s[i]);
if(!ch[u][c])return 0;
u=ch[u][c];
}
return val[u];
}
};
struct s_ans
{
int x,y;
int c;
};
int dx[]={-1,-1,0,1,1,1,0,-1};
int dy[]={0,1,1,1,0,-1,-1,-1};
s_ans ans[maxn];
char g[maxn][maxn];
char word[maxn][maxn];
int n,m,r;
trie ti;
void init()
{
scanf("%d%d%d",&n,&m,&r);
for(int i=0; i<n; i++)
{
scanf("%s",g[i]);
}
for(int i=1; i<=r; i++)
{
scanf("%s",word[i]);
ti.insert(word[i],i);
}
}
bool check(int x,int y)
{
if(x>=n||x<0||y<0||y>m)return false;
return true;
}
void get_ans(int icount,int pos,int ox,int oy)
{
if(icount)
{
int u=icount;
ans[u].x=ox;
ans[u].y=oy;
ans[u].c=pos;
}
}
void cal(int sz,int x,int y,int i,int ox ,int oy)
{
int c=ti.idx(g[x][y]);
if(ti.ch[sz][c])
{
get_ans(ti.val[ti.ch[sz][c]],i,ox,oy);
int nx=x+dx[i];
int ny=y+dy[i];
if(check(nx,ny))
cal(ti.ch[sz][c],nx,ny,i,ox,oy);
}
}
void slove()
{
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
for(int k=0; k<8; k++)
{
cal(0,i,j,k,i,j);
}
}
}
for(int i=1; i<=r; i++)
printf("%d %d %c\n",ans[i].x,ans[i].y,ans[i].c+'A');
}
int main()
{
init();
slove();
return 0;
}