zoukankan      html  css  js  c++  java
  • POJ 1204 AC自动机

    链接:

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

    题意:

    给定一个n*m的大写字母组成的矩阵,再给定C个单词,这些单词可能出现在矩阵中,出现的方向可能是上、下、左、右、左上、右上、左下、右下

    问这C个单词的第一个字母出现在矩阵中的什么位置,以及出现的方向。

    题解:

    这题有两种解法,第一种是用字典树+深搜,用单词建立一颗字典树,然后八个方向去深搜,很容易想也很容易写,这种方法在数据很给力的的时候就会超时,所以不多讲。

    第二种方法是AC自动机,在AC自动机题目中算比较常规的字符串匹配问题。

    由于要记录每个单词单词在矩阵的第一个字母顺序和方向,这有些困难,因为在匹配的过程中初始没办法回溯求初始位置,硬要这样的话肯定也行,比较麻烦。

    考虑将单词反转,这样就是最后匹配到的那个位置,这样就不要回溯。

    建好字典树后改装成AC自动机,然后在矩阵中从12个方向去查询,如果遇到危险节点(某个单词在这里结束)就可以记录这个单词的位置和方向了。

    这里并不需要记录12个方向的字符串,只要在查询的过程按照某个方向一直走就好。

    代码:

     31 int n, m, w;
     32 string s[MAXN];
     33 int pos[MAXN][3];
     34 int dir[8][2] = { 0,1,0,-1,1,0,-1,0,1,1,-1,-1,1,-1,-1,1 };
     35 char ch[9] = "CGEADHFB";
     36 int head, tail;
     37 
     38 struct node {
     39     node *fail;
     40     node *next[26];
     41     int id;
     42     node() {
     43         fail = NULL;
     44         id= 0;
     45         rep(i, 0, 26) next[i] = NULL;
     46     }
     47 }*q[1000010];
     48 node *root;
     49 
     50 void insert(string s, int id) {
     51     node *p = root;
     52     int len = s.length();
     53     rep(i, 0, len) {
     54         int temp = s[i] - 'A';
     55         if (p->next[temp] == NULL) p->next[temp] = new node();
     56         p = p->next[temp];
     57     }
     58     p->id = id;
     59 }
     60 
     61 void build_ac() {
     62     q[tail++] = root;
     63     while (head != tail) {
     64         node *p = q[head++];
     65         node *temp = NULL;
     66         rep(i, 0, 26) if (p->next[i] != NULL) {
     67             if (p == root) p->next[i]->fail = root;
     68             else {
     69                 temp = p->fail;
     70                 while (temp != NULL) {
     71                     if (temp->next[i] != NULL) {
     72                         p->next[i]->fail = temp->next[i];
     73                         break;
     74                     }
     75                     temp = temp->fail;
     76                 }
     77                 if (temp == NULL) p->next[i]->fail = root;
     78             }
     79             q[tail++] = p->next[i];
     80         }
     81     }
     82 }
     83 
     84 void query(int x, int y, int d, int id) {
     85     node *p = root;
     86     while (x >= 0 && x < n && y >= 0 && y < m) {
     87         int index = s[x][y] - 'A';
     88         while (p->next[index] == NULL && p != root) p = p->fail;
     89         p = p->next[index];
     90         if (p == NULL) p = root;
     91         node *temp = p;
     92         while (temp != root && temp->id) {
     93             int k = temp->id;
     94             if (pos[k][0] > x || pos[k][0] == x && pos[k][1] > y)
     95                 pos[k][0] = x, pos[k][1] = y, pos[k][2] = id;
     96             temp = temp->fail;
     97         }
     98         x += dir[d][0];
     99         y += dir[d][1];
    100     }
    101 }
    102 
    103 int main() {
    104     ios::sync_with_stdio(false), cin.tie(0);
    105     cin >> n >> m >> w;
    106     root = new node(); 
    107     rep(i, 0, n) cin >> s[i];
    108     rep(i, 1, w + 1) {
    109         string a;
    110         cin >> a;
    111         reverse(all(a));
    112         insert(a, i);
    113         pos[i][0] = pos[i][1] = INF;
    114     }
    115     build_ac();
    116     rep(i, 0, n) {
    117         query(i, 0, 0, 1), query(i, m - 1, 1, 0);
    118         query(i, 0, 7, 6), query(i, m - 1, 6, 7);
    119         query(i, 0, 4, 5), query(i, m - 1, 5, 4);
    120     }
    121     rep(i, 0, m) {
    122         query(0, i, 2, 3), query(n - 1, i, 3, 2);
    123         query(0, i, 6, 7), query(n - 1, i, 7, 6);
    124         query(0, i, 4, 5), query(n - 1, i, 5, 4);
    125     }
    126     rep(i, 1, w + 1)
    127         cout << pos[i][0] << ' ' << pos[i][1] << ' ' << ch[pos[i][2]] << endl;
    128     return 0;
    129 }
  • 相关阅读:
    params
    robotframework+jenkins分布式执行自动化测试用例
    python文件读写
    Robot Framework资料
    RobotFramework环境搭建
    Django评论系统
    Django集成TinyMCE(admin后台+前台)
    个人博客模块分析
    Django实战,小网站实现增删改查
    docker入门【1】
  • 原文地址:https://www.cnblogs.com/baocong/p/6793104.html
Copyright © 2011-2022 走看看