#include<stdio.h>
#include<string.h>
const int MAX_CHARN=26;
const int MAXL=1000;
const int MAXC=1000;
const int MAXW=1000;
const int MAX_WORD_LEN=1000;
const int DIR[8][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
struct Answer{
int r,c;
char o;
Answer(int i, int j, char d){
r=i;
c=j;
o=d;
}
};
struct TrieNode{
bool isWord;
Answer* ans;
TrieNode* child[MAX_CHARN];
TrieNode(){
int i;
isWord=false;
ans=NULL;
for(i=0;i<MAX_CHARN;i++){
child[i]=NULL;
}
}
};
int L, C, W;
char puzzle[MAXL][MAXC];
char word[MAXW][MAX_WORD_LEN+1];
int maxlen;
TrieNode* trieRoot;
//求出字符c在字符集中的索引并返回.
inline int Index(char c);
//将字符串word插入根为root的Trie树中.
void InsertWord(TrieNode* &root, char* word);
//在根为root的Trie树中查找字符串word.
//存在时,返回word尾字符在Trie中的结点;不存在时,返回NULL.
TrieNode* SearchWord(TrieNode* root, char* word);
int main()
{
TrieNode* p;
TrieNode* q;
int i, j, k;
scanf("%d%d",&L,&C,&W);
for(i=0;i<L;i++){
scanf("%d",puzzle[i]);
}
trieRoot=NULL;
for(i=0;i<W;i++){
scanf("%d",word[i]);
int len=strlen(word[i]);
if(maxlen<len){
maxlen=len;
}
InsertWord(trieRoot,word[i]);
}
//遍历字谜表格,检查字谜表格中允许的字符串是否在目标单词集合中,使用Trie树实现
char curword[MAX_WORD_LEN+1];
int nsol=0;
for(i=0;i<L;i++){
for(j=0;j<C;j++){
for(k=0;k<8;k++){
int r=i,c=j,len=1;
p=trieRoot;
while(len<=maxlen){
if(0<=r&&r<L&&0<=c&&c<C){
curword[len-1]=puzzle[r][c];
curword[len]='\0';
q=p->child[Index(curword[len-1])];
if(q==NULL){
break;
}
else if(q->isWord&&q->ans==NULL){
q->ans=new Answer(i,j,'A'+k);
nsol++;
if(nsol==W){
break;
}
}
len++;
r+=DIR[k][0];
c+=DIR[k][1];
p=q;
}
else{
break;
}
}
if(nsol==W){
break;
}
}
if(nsol==W){
break;
}
}
if(nsol==W){
break;
}
}
for(i=0;i<W;i++){
p=SearchWord(trieRoot,word[i]);
printf("%d%d%c\n",p->ans->r,p->ans->c,p->ans->o);
}
return 0;
}
inline int Index(char c)
{
return int(c-'A');
}
void InsertWord(TrieNode* &root, char* word)
{
if(root==NULL){
root=new TrieNode();
}
TrieNode* p=root;
while(*word!='\0'){
int ind=Index(*word);
if(p->child[ind]==NULL){
p->child[ind]=new TrieNode();
}
p=p->child[ind];
word++;
}
p->isWord=true;
}
TrieNode* SearchWord(TrieNode* root, char* word)
{
TrieNode* p=root;
while(*word!='\0'){
int ind=Index(*word);
if(p->child[ind]==NULL){
return NULL;
}
p=p->child[ind];
word++;
}
if(p!=NULL&&p->isWord){
return p;
}
return NULL;
}