题意
传送门 AOJ 2212
题解
A C AC AC 自动机预处理出迷宫路线对应的字符串的后缀模式。以后缀模式为状态,若状态对应节点或其失配指针指向的节点为禁止模式串,则此状态包含禁止模式。
以坐标位置、路线后缀状态为总的状态, B F S BFS BFS 求最短路即可。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 55
#define maxp 105
struct node
{
int x, y, s, d;
node() {}
node(int x, int y, int s, int d) : x(x), y(y), s(s), d(d) {}
};
int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, 1, -1};
int N, M, P, sx, sy, tx, ty, ns, id['Z' + 1];
int trie[maxp][4], fail[maxp], flag[maxp], used[maxn][maxn][maxp];
char mat[maxn][maxn];
void insert(char *s)
{
int len = strlen(s), p = 0;
for (int i = 0; i < len; i++)
{
int c = id[s[i]];
if (!trie[p][c])
{
memset(trie[ns], 0, sizeof(trie[ns]));
trie[p][c] = ns++;
}
p = trie[p][c];
}
flag[p] = 1;
}
void getFail()
{
queue<int> q;
for (int i = 0; i < 4; i++)
{
if (trie[0][i])
{
fail[trie[0][i]] = 0;
q.push(trie[0][i]);
}
}
while (!q.empty())
{
int p = q.front();
q.pop();
if (flag[fail[p]])
{
flag[p] = 1;
}
for (int i = 0; i < 4; i++)
{
if (trie[p][i])
{
fail[trie[p][i]] = trie[fail[p]][i];
q.push(trie[p][i]);
}
else
{
trie[p][i] = trie[fail[p]][i];
}
}
}
}
int main()
{
id['U'] = 0, id['D'] = 1, id['R'] = 2, id['L'] = 3;
while (~scanf("%d%d", &N, &M) && (N | M))
{
for (int i = 0; i < N; i++)
{
scanf(" %s", mat[i]);
for (int j = 0; j < M; j++)
{
if (mat[i][j] == 'S')
{
sx = i, sy = j;
}
if (mat[i][j] == 'G')
{
tx = i, ty = j;
}
}
}
scanf("%d", &P);
ns = 1;
memset(flag, 0, sizeof(flag));
memset(trie[0], 0, sizeof(trie[0]));
for (int i = 0; i < P; i++)
{
char s[15];
scanf(" %s", s);
insert(s);
}
getFail();
int res = inf;
queue<node> q;
q.push(node(sx, sy, 0, 0));
memset(used, 0, sizeof(used));
while (!q.empty())
{
node p = q.front();
q.pop();
int x = p.x, y = p.y, s = p.s, d = p.d;
if (x == tx && y == ty)
{
res = d;
break;
}
if (used[x][y][s])
{
continue;
}
used[x][y][s] = 1;
for (int i = 0; i < 4; i++)
{
if (flag[trie[s][i]])
{
continue;
}
int nx = x + dx[i], ny = y + dy[i];
if (nx >= 0 && nx < N && ny >= 0 && ny < M && mat[nx][ny] != '#')
{
q.push(node(nx, ny, trie[s][i], d + 1));
}
}
}
printf("%d\n", res == inf ? -1 : res);
}
return 0;
}