转于:http://hi.baidu.com/fujj314/blog/item/378425abe3a30df31f17a23d.html
题目大意:是给出一个单词表,然后给出几组字符串,要你求出字符串在单词表匹配的起始位置,和搜寻方向
解题思路:AC自动机,tries图,看到这么多个方向,多个单词,想到了多模式字符串匹配。
AC自动机,tries图的原理和建立参考这个文档,讲得很详细http://wenku.baidu.com/view/af921feb6294dd88d0d26b47.html
应该把字符串建立tries图,用单词表建立的话,每个位置每个方向的单词都得建立tires图~~不可取
建好tries图之后,枚举单词表每个起点,每个方向与tries图是否匹配
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int kind = 26;
const int maxn = 1001;
struct node
{
node *fail;
int num;
node *next[kind];
node()
{
fail = NULL;
num = -1;
memset(next, 0, sizeof(next));
}
};
int dir[8][2] = {{-1, 0,}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};
char words[maxn][maxn], database[maxn][maxn];
int l, c, w, id, len[maxn], ans[maxn][3];
void insert(char *str, node *root, int n);
void build(node *root);
void search(node *root, int x, int y, int k);
inline bool ok(int x, int y);
int main()
{
node *root = new node();
id = 0;
scanf("%d %d %d", &l, &c, &w);
for(int i = 0; i < l; i++)
scanf("%s", database[i]);
for(int i = 0; i < w; i++)
{
scanf("%s", words[i]);
insert(words[i], root, i);
}
build(root);
for(int i = 0; i < l; i++)
{
for(int k = 0; k < 8; k++)
{
search(root, i, 0, k);
search(root, i, c - 1, k);
}
}
for(int j = 0; j < c; j++)
{
for(int k = 0; k < 8; k++)
{
search(root, 0, j, k);
search(root, l - 1, j, k);
}
}
for(int i = 0; i < w; i++)
printf("%d %d %c\n", ans[i][0], ans[i][1], 'A' + ans[i][2]);
return 0;
}
inline bool ok(int x, int y)
{
return (x >= 0 && x < l && y >= 0 && y < c);
}
void insert(char *str, node *root, int n)
{
int i, index;
len[n] = strlen(str);
node *p = root;
for(i = 0; i < len[n]; i++)
{
index = str[i] - 'A';
if(!p->next[index])
break;
p = p->next[index];
}
for(; i < len[n]; i++)
{
index = str[i] - 'A';
node *tmp = new node();
p->next[index] = tmp;
p = tmp;
}
p->num = id++;
}
void build(node *root)
{
queue<node *> que;
node *tmp;
root->fail = NULL;
que.push(root);
while(!que.empty())
{
node *p = que.front();
que.pop();
tmp = NULL;
for(int i = 0; i < kind; i++)
{
if(p->next[i] != NULL)
{
if(p == root)
p->next[i]->fail = root;
else
{
tmp = p->fail;
while(tmp != NULL)
{
if(tmp->next[i] != NULL)
{
p->next[i]->fail = tmp->next[i];
break;
}
tmp = tmp->fail;
}
if(!tmp)
p->next[i]->fail = root;
}
que.push(p->next[i]);
}
}
}
}
void search(node *root, int x, int y, int k)
{
node *p = root, *q;
int index;
while(ok(x, y))
{
index = database[x][y] - 'A';
while(p->next[index] == NULL && p != root)
p = p->fail;
p = p->next[index];
if(p == NULL)
p = root;
q = p;
while(q != NULL && q->num != -1)
{
ans[q->num][0] = x - (len[q->num] - 1) * dir[k][0];
ans[q->num][1] = y - (len[q->num] - 1)* dir[k][1];
ans[q->num][2] = k;
q->num = -1;
q = q->fail;
}
x += dir[k][0];
y += dir[k][1];
}
}