Time Limit: 5000MS | Memory Limit: 65536K | |||
Total Submissions: 6543 | Accepted: 2486 | Special Judge |
Description
Input
Output
#include
#include
#define maxn 1000001
#define maxn2 1002
#define maxn3 100
#define maxn4 2000000
#define kind 26
#define clear(a,b) memset(a,b,sizeof(a))
const int di[8][2] = {{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
const char tranf[8] = {'E','F','G','H','A','B','C','D'};
char ma[maxn2][maxn2];
int X[maxn2],Y[maxn2],dir[maxn2];
struct AC_node{
int a,b;
struct AC_node *next[kind],*fail;
AC_node(){
fail = NULL;
a = 0;
b = 0;
clear(next,NULL);
}
} *q[maxn];
char s1[maxn3],txt[maxn4];
void AC_trie(struct AC_node *T,char s[],int t)
{
int k,i = strlen(s)-1;
struct AC_node *op = T;
while(i >= 0) {
k = s[i] - 'A';
if (op->next[k] == NULL) op->next[k] = new AC_node();
op = op->next[k];
i--;
}
op->a++;
op->b = t;
}
void AC_build(struct AC_node *T)
{
int i,h = 0,t = 0;
struct AC_node *op,*tt;
clear(q,NULL);
T->fail = NULL;
q[t++] = T;
while (h < t) {
op = q[h++];
for(i = 0;i < kind;i++) {
if (op->next[i]!=NULL) {
if (op == T) op->next[i]->fail = T;
else {
tt = op->fail;
while(tt != NULL) {
if (tt->next[i] != NULL) {
op->next[i]->fail = tt->next[i];
break;
}
tt = tt->fail;
}
if (tt == NULL) op->next[i]->fail = T;
}
q[t++] = op->next[i];
}
}
}
}
int AC_query(struct AC_node *T,int x,int y,int d)
{
int i = 0,ans = 0,k;
struct AC_node *op = T;
while(ma[x][y]) {
k = ma[x][y] - 'A';
while(op->next[k] == NULL && op != T) op = op->fail;
op = op->next[k];
op = (op == NULL)?T:op;
struct AC_node *tmp = op;
while(tmp != T) {
if (tmp->a > 0) {
if (x < X[tmp->b] || (x == X[tmp->b] && y < Y[tmp->b])) {
X[tmp->b] = x;
Y[tmp->b] = y;
dir[tmp->b] = d;
}
}
tmp = tmp->fail;
}
x+=di[d][0];
y+=di[d][1];
}
return ans;
}
int main()
{
int j,m,n,i,k;
scanf("%d%d%d",&m,&n,&k);
clear(ma,0);
getchar();
for(i = 1;i <= m;i++,getchar())
for(j = 1;j <= n;j++) scanf("%c",&ma[i][j]);
struct AC_node *root = new AC_node();
for(i = 1;i <= k;i++) {
X[i] = maxn;
Y[i] = maxn;
scanf("%s",s1);
AC_trie(root,s1,i);
}
AC_build(root);
for(i = 1;i <= m;i++) {AC_query(root,i,1,2);AC_query(root,i,n,6);}
for(i = 1;i <= n;i++) {AC_query(root,1,i,4);AC_query(root,m,i,0);}
for(i = 1;i <= n;i++) {AC_query(root,1,i,3);AC_query(root,1,i,5);AC_query(root,m,i,7);AC_query(root,m,i,1);}
for(i = 1;i <= m;i++) {AC_query(root,i,1,1);AC_query(root,i,1,3);AC_query(root,i,n,5);AC_query(root,i,n,7);}
for(i = 1;i <= k;i++) printf("%d %d %c\n",X[i]-1,Y[i]-1,tranf[dir[i]]);
return 0;
}