当前位置: 代码迷 >> 综合 >> poj - 1204 - Word Puzzles(AC自动机)
  详细解决方案

poj - 1204 - Word Puzzles(AC自动机)

热度:41   发布时间:2024-01-10 13:20:25.0

题意:给出一个L*C的大写字母矩阵,再给出W个由大写字母组成的单词,求这些单词在矩阵中出现的位置及方向(0 < L <= 1000,0 < C <= 1000,0 < W <= 1000)。

题目链接:http://poj.org/problem?id=1204

——>>看到这题目,Sample好长啊~其实只是AC自动机,从边到边,枚举匹配。

#include <cstdio>
#include <cstring>
#include <queue>using namespace std;const int maxn = 1000 + 10;int L, C, W;
char G[maxn][maxn], w[maxn];
int dx[] = {-1, -1, 0, 1, 1,  1,  0, -1};
int dy[] = { 0,  1, 1, 1, 0, -1, -1, -1};struct Point{int l;int c;int d;
}ret[maxn];struct node{int id;int wlen;node *next[26];node *fail;node(){id = -1;wlen = -1;memset(next, 0, sizeof(next));fail = NULL;}
};struct AC{node *root;void init(){root = new node;}int idx(char c){return c - 'A';}void insert(char *s, int id){int len = strlen(s);node *p = root;for(int i = 0; i < len; i++){int c = idx(s[i]);if(!p->next[c]) p->next[c] = new node;p = p->next[c];}p->id = id;p->wlen = len;}void getFail(){root->fail = NULL;queue<node*> qu;qu.push(root);while(!qu.empty()){node *r = qu.front(); qu.pop();for(int c = 0; c < 26; c++) if(r->next[c]){node *u = r->next[c];qu.push(u);node *v = r->fail;while(v && !v->next[c]) v = v->fail;if(v) u->fail = v->next[c];else u->fail = root;}}}void find(int x, int y, char d){node *j = root;while(x >= 0 && x < L && y >= 0 && y < C){int c = idx(G[x][y]);while(j && !j->next[c]) j = j->fail;if(j) j = j->next[c];else j = root;node *p = j;while(p != root && p->id != -1){ret[p->id].l = x - dx[idx(d)] * (p->wlen - 1);ret[p->id].c = y - dy[idx(d)] * (p->wlen - 1);ret[p->id].d = d;p = p->fail;}x += dx[idx(d)];y += dy[idx(d)];}}
}ac;void read(){ac.init();for(int i = 0; i < L; i++){getchar();for(int j = 0; j < C; j++) G[i][j] = getchar();}for(int i = 0; i < W; i++){scanf("%s", w);ac.insert(w, i);}
}void solve(){ac.getFail();for(int i = 0; i < L; i++){ac.find(i, 0, 'B');ac.find(i, 0, 'C');ac.find(i, 0, 'D');ac.find(i, C-1, 'F');ac.find(i, C-1, 'G');ac.find(i, C-1, 'H');}for(int i = 0; i < C; i++){ac.find(0, i, 'D');ac.find(0, i, 'E');ac.find(0, i, 'F');ac.find(L-1, i, 'A');ac.find(L-1, i, 'B');ac.find(L-1, i, 'H');}for(int i = 0; i < W; i++) printf("%d %d %c\n", ret[i].l, ret[i].c, ret[i].d);
}int main()
{while(scanf("%d%d%d", &L, &C, &W) == 3){read();solve();}return 0;
}


  相关解决方案