POJ 1204 Word Puzzles ac自动机

来源:互联网 发布:郑州报警网络 编辑:程序博客网 时间:2024/05/08 09:14

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

题意:给一个n * m的字符矩阵,然后给一些模式串,问模式串能不能再字符矩阵中找到,可以从八个方向找

思路:对模式串建ac自动机,然后对于字符矩阵,把所有边上的点从八个方向枚举字符串,去自动机中匹配能不能找到模式串

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define debug puts("here")using namespace std;const int N = 1100;int dir[8][2] = {-1, 0, -1, 1, 0, 1, 1, 1, 1, 0, 1, -1, 0, -1, -1, -1};struct node{    int id;    node *fail;    node *next[26];    node()    {        id = -1;        fail = NULL;        memset(next, 0, sizeof next);    }}*que[N*N];node *root;char s[N][N], str[N];int n, m, q;int nowx, nowy, nowd;int res[N][3];int len[N];void _insert(char *s, node *root, int id){    node *p = root;    for(int i = 0; s[i]; i++)    {        int j = s[i] - 'A';        if(p -> next[j] == NULL)            p -> next[j] = new node();        p = p -> next[j];    }    p -> id = id;}void ac_automation(node *root){    int head = 0, tail = 0;    que[tail++] = root;    while(head != tail)    {        node *p = que[head++];        node *tmp = NULL;        for(int i = 0; i < 26; 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 == NULL) p -> next[i] -> fail = root;                }                que[tail++] = p -> next[i];            }        }    }}void judge(int i, int id, char *s){    res[id][0] = nowx + dir[nowd][0] * (i - len[id] + 1);    res[id][1] = nowy + dir[nowd][1] * (i - len[id] + 1);    res[id][2] = nowd;}int query(char *s, node *root){    int cnt = 0;    node *p = root;    for(int i = 0; s[i]; i++)    {        int j = s[i] - 'A';        while(p -> next[j] == NULL && p != root)            p = p -> fail;        p = p -> next[j];        if(p == NULL) p = root;        node *tmp = p;        while(tmp != root)        {            if(tmp -> id != -1)                judge(i, tmp -> id, s);            tmp = tmp -> fail;        }    }    return cnt;}void work(int x, int y, int k){    char str[N];    int cnt = 0;    nowx = x, nowy = y, nowd = k;    str[cnt++] = s[x][y];    while(true)    {        x += dir[k][0], y += dir[k][1];        if(x >= 0 && x < n && y >= 0 && y < m)            str[cnt++] = s[x][y];        else break;    }    str[cnt++] = '\0';    query(str, root);}void solve(){    for(int i = 0; i < n; i++)        for(int j = 0; j < 8; j++)        {            work(i, 0, j);            work(i, m - 1, j);        }    for(int i = 0; i < m; i++)        for(int j = 0; j < 8; j++)        {            work(0, i, j);            work(n - 1, i, j);        }    for(int i = 0; i < q; i++)        printf("%d %d %c\n", res[i][0], res[i][1], res[i][2] + 'A');}int main(){    while(~ scanf("%d%d%d", &n, &m, &q))    {        root = new node();        for(int i = 0; i < n; i++)            scanf("%s", s[i]);        for(int i = 0; i < q; i++)        {            scanf("%s", str);            len[i] = strlen(str);            _insert(str, root, i);        }        ac_automation(root);        solve();    }    return 0;}


0 0
原创粉丝点击