/*
http://acm.pku.edu.cn/JudgeOnline/problem?id=1204
第一次用Trie树,这题算是比较折腾了,遇到的问题如下
1)一开始的思路是对输入图枚举每一个位置及每一个方向插入到trie树中,然后对
每一个待搜索单词进行搜索,结果MLE
2)思考了一下如果按1)的方法插入数据量太大,MLE也是情理之中的,接着换了思路
为何不逆向来,这次是将待搜索单词插入到trie树中,然后枚举各个待搜索单词去trie
树中搜索,MLE没有了,但是又TLE,天啊,怎么回事?
3)接下来舍弃了STL的string,改为char + scanf来输入,照样TLE,看来不是输入的问题
4)紧接着仔细读了自己的程序,终于中到了一处可疑的地方.原来自己在枚举各个方向单词
的时候是先构造单词,等够咱完后再放入到trie树中搜索,但是这两个步骤是可以合二
为一的即一边构造一般搜索,这样时间大大缩小了,改完后提交就AC了,这题好汗啊,前前
后后一共交了6次
*/
#include <iostream>
#include <string>
#define MAX_N 1000
#define MAX_L 26
using namespace std;
char input[MAX_N + 2][MAX_N + 2];
int countv = 0;
int dir[8][2] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};
int rowN, colN, strNum;
struct node
{
bool v;
int row, col;
char dir;
}quess[MAX_N + 1];
bool inRange(int row, int col)
{
return row >= 0 && row < rowN && col >= 0 && col < colN;
}
class TrieTree
{
protected:
struct TrieNode;
public:
TrieTree();
~TrieTree();
int search(int row, int col, int dir) const; //0:not found; 1:found
void insert(char indexStr[], int index);
protected:
struct TrieNode
{
int index;
TrieNode *branch[MAX_L];
TrieNode();
};
TrieNode *root;
};
TrieTree::TrieTree()
{
root = NULL;
}
TrieTree::~TrieTree()
{
delete root;
root = NULL;
}
TrieTree::TrieNode::TrieNode()
{
index = -1;
for(int i = 0; i < MAX_L; i++)
branch[i] = NULL;
}
void TrieTree::insert(char indexStr[], int index)
{
char c;
int indexPos = 0;
if(root == NULL)
root = new TrieNode();
TrieNode *curNode = root;
for(indexPos = 0; indexPos < strlen(indexStr); indexPos++)
{
c = indexStr[indexPos];
if(curNode->branch[c - 'A'] == NULL)
curNode->branch[c - 'A'] = new TrieNode();
curNode = curNode->branch[c - 'A'];
}
curNode->index = index;
}
int TrieTree::search(int row, int col, int d) const
{
char c;
int indexPos = 0, curRow = row, curCol = col;
if(root == NULL)
return 0;
TrieNode *curNode = root;
while(inRange(curRow, curCol))
{
c = input[curRow][curCol];
if(curNode->branch[c - 'A'] == NULL)
return 0;
curNode = curNode->branch[c - 'A'];
if(curNode->index != -1)
{
if(!quess[curNode->index].v)
{
countv++;
quess[curNode->index].row = row;
quess[curNode->index].col = col;
quess[curNode->index].dir = d + 'A';
quess[curNode->index].v = true;
}
}
if(countv == strNum)
return 1;
curRow = curRow + dir[d][0];
curCol = curCol + dir[d][1];
}
return 1;
}
void search(TrieTree *tt)
{
int i, j, d;
string temp;
for(i = 0; i < rowN; i++)
{
for(j = 0; j < colN; j++)
{
for(d = 0; d < 8; d++)
{
tt->search(i, j, d);
if(countv == strNum)
return;
}
}
}
}
int main()
{
int i;
cin>>rowN>>colN>>strNum;
TrieTree *tt = new TrieTree();
for(i = 0; i < rowN; i++)
scanf("%s", input[i]);
char input[MAX_N + 2];
for(i = 0; i < strNum; i++)
{
scanf("%s", input);
tt->insert(input, i);
}
search(tt);
for(i = 0; i < strNum; i++)
cout<<quess[i].row<<" "<<quess[i].col<<" "<<quess[i].dir<<endl;
return 0;
}