题目大意;原题链接
给定一个字符串矩阵和待查找的单词,可以朝8个不同的方向查找,输出待查找单词第一个字母在矩阵中出现的位置和该单词被查到的方向.
A~H代表8个不同的方向,A代表正北方向,其他依次以45度角的方向顺时针增加.
解题思路:
解法一:Trie树暴搜
因为不查询重复单词,所以dfs(int u,int i,int j,int k)函数中当已经查询到单词时,val[u]可以置零做标记.
#include<cstdio> #include<cstring> #define maxn 200010 using namespace std; bool vis[26]; int n,m,w,x,y,sz=1;//sz得为全局变量 char str[1010][1010],word[1010]; int val[maxn],out[1010][3]; int dir[8][2]={-1,0,-1,1,0,1,1,1,1,0,1,-1,0,-1,-1,-1};//顺时针 struct Trie { int next[26]; }trie[maxn]; void insert(char *s,int k) { int u=0,len=strlen(s); for(int i=0;i<len;i++){ int id=s[i]-‘A‘; if(!trie[u].next[id]) trie[u].next[id]=sz++; u=trie[u].next[id]; } val[u]=k;//u为结点编号,k为单词编号 } void dfs(int u,int i,int j,int k)//k记录方向 { if(u==0||i<0||i>=n||j<0||j>=m) return;//该语句之前放在if(val[u])条件之后,WA if(val[u]){ out[val[u]][0]=x; out[val[u]][1]=y; out[val[u]][2]=k; val[u]=0;//做标记,因为不查询重复单词 } int id=str[i+dir[k][0]][j+dir[k][1]]-‘A‘; dfs(trie[u].next[id],i+dir[k][0],j+dir[k][1],k);//必须得朝同一方向搜索 } int main() { scanf("%d%d%d",&n,&m,&w); for(int i=0;i<n;i++) scanf("%s",str[i]); for(int i=1;i<=w;i++){ scanf("%s",word); insert(word,i); vis[word[0]-‘A‘]=1; } for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(vis[str[i][j]-‘A‘]){ for(int k=0;k<8;k++){ x=i,y=j;//记录下最初的位置,从Trie树根开始向下搜索 dfs(trie[0].next[str[i][j]-‘A‘],i,j,k); } } } } for(int i=1;i<=w;i++) printf("%d %d %c\n",out[i][0],out[i][1],out[i][2]+‘A‘); return 0; }
原文:http://www.cnblogs.com/freinds/p/6443109.html