poj 1204 Word Puzzles (ac自动机)

题意:

给出一个字符串矩阵,n个单词,要求n个单词去匹配这个矩阵,单词可以出现矩阵任意位置,可以斜着,横着,竖着。求出每个单词的首字母在矩阵中的位置,以及方向。

题解:

枚举起点,和方向,在矩阵中暴力匹配。

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define B(x) (1<<(x))
typedef __int64 ll;
typedef unsigned __int64 Ull;
const int oo=0x3f3f3f3f;
const ll OO=1LL<<61;
const Ull MOD=1000000;
const int maxn=1005;
const int SIZE=1000005;
const int type=26;
char str[maxn];
char maze[maxn][maxn];
int d[8][2] = {
    {-1,0},{-1,1},{0,1},{1,1},
    {1,0},{1,-1},{0,-1},{-1,-1}
};
char getdir[]={'A','B','C','D','E','F','G','H'};
struct Node
{
    int x,y;
    char dir;
}ans[maxn];
int R,C;

struct ACautomaton
{
    int next[SIZE][type],fail[SIZE],ID[SIZE],length[SIZE];
    int cnt,root;

    int newNode()
    {
        for(int i=0;i<type;i++)
            next[cnt][i]=-1;
        ID[cnt++]=0;
        return cnt-1;
    }

    void Init()
    {
        cnt=0;
        root=newNode();
    }

    void Insert(char buff[],int id)
    {
        int now=root;
        int len=strlen(buff);
        for(int i=0,k;i<len;i++)
        {
            k=buff[i]-'A';
            if(next[now][k]==-1)
                next[now][k]=newNode();
            now=next[now][k];
        }
        ID[now]=id;
        length[now]=len;
    }

    void build()
    {
        fail[root]=root;
        int now=root;
        queue<int>Q;
        for(int i=0;i<type;i++)
        {
            if(next[now][i]==-1)
                next[now][i]=root;
            else
            {
                fail[next[now][i]]=root;
                Q.push(next[now][i]);
            }
        }
        while(!Q.empty())
        {
            now=Q.front();
            Q.pop();
            for(int i=0;i<type;i++)
            {
                if(next[now][i]==-1)
                    next[now][i]=next[fail[now]][i];
                else
                {
                    fail[next[now][i]]=next[fail[now]][i];
                    Q.push(next[now][i]);
                }
            }
        }
    }

    void Find(int x,int y,int k)
    {
        int now=root,t,temp;
        int prex=x,prey=y;
        while(x>=0&&y>=0&&x<R&&y<C)
        {
            t=maze[x][y]-'A';
            now=next[now][t];
            temp=now;
            if(temp!=root)
            {
                if(ID[temp])
                {
                    ans[ID[temp]].x=x-d[k][0]*(length[temp]-1);
                    ans[ID[temp]].y=y-d[k][1]*(length[temp]-1);
                    ans[ID[temp]].dir=getdir[k];
                    ID[temp]=0;
                }
                temp=fail[temp];
            }
            x=x+d[k][0];
            y=y+d[k][1];
        }
    }

    void Search()
    {
        for(int i=0;i<R;i++)
        {
            Find(i,0,1);
            Find(i,0,2);
            Find(i,0,3);
            Find(i,C-1,6);
            Find(i,C-1,5);
            Find(i,C-1,7);
        }
        for(int i=0;i<C;i++)
        {
            Find(0,i,3);
            Find(0,i,4);
            Find(0,i,5);
            Find(R-1,i,0);
            Find(R-1,i,1);
            Find(R-1,i,7);
        }
    }

}ac;

int main()
{
    int L;
    while(scanf("%d %d %d",&R,&C,&L)!=EOF)
    {
        ac.Init();
        for(int i=0;i<R;i++)
            scanf("%s",maze[i]);
        for(int i=1;i<=L;i++)
        {
            scanf("%s",str);
            ac.Insert(str,i);
        }
        ac.build();
        ac.Search();
        for(int i=1;i<=L;i++)
            printf("%d %d %c\n",ans[i].x,ans[i].y,ans[i].dir);
    }
    return 0;
}
/**
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19
0  Q  W  S  P  I  L  A  A  T  I  R  A  G  R  A  M  Y  K  E  I
1  A  G  T  R  C  L  Q  A  X  L  P  O  I  J  L  F  V  B  U  Q
2  T  Q  T  K  A  Z  X  V  M  R  W  A  L  E  M  A  P  K  C  W
3  L  I  E  A  C  N  K  A  Z  X  K  P  O  T  P  I  Z  C  E  O
4  F  G  K  L  S  T  C  B  T  R  O  P  I  C  A  L  B  L  B  C
5  J  E  W  H  J  E  E  W  S  M  L  P  O  E  K  O  R  O  R  A
6  L  U  P  Q  W  R  N  J  O  A  A  G  J  K  M  U  S  J  A  E
7  K  R  Q  E  I  O  L  O  A  O  Q  P  R  T  V  I  L  C  B  Z
8  Q  O  P  U  C  A  J  S  P  P  O  U  T  M  T  S  L  P  S  F
9  L  P  O  U  Y  T  R  F  G  M  M  L  K  I  U  I  S  X  S  W
10 W  A  H  C  P  O  I  Y  T  G  A  K  L  M  N  A  H  B  V  A
11 E  I  A  K  H  P  L  B  G  S  M  C  L  O  G  N  G  J  M  L
12 L  D  T  I  K  E  N  V  C  S  W  Q  A  Z  U  A  O  E  A  L
13 H  O  P  L  P  G  E  J  K  M  N  U  T  I  I  O  R  M  N  C
14 L  O  I  U  F  T  G  S  Q  A  C  A  X  M  O  P  B  E  I  O
15 Q  O  A  S  D  H  O  P  E  P  N  B  U  Y  U  Y  O  B  X  B
16 I  O  N  I  A  E  L  O  J  H  S  W  A  S  M  O  U  T  R  K
17 H  P  O  I  Y  T  J  P  L  N  A  Q  W  D  R  I  B  I  T  G
18 L  P  O  I  N  U  Y  M  R  T  E  M  P  T  M  L  M  N  B  O
19 P  A  F  C  O  P  L  H  A  V  A  I  A  N  A  L  B  P  F  S
*/







你可能感兴趣的:(poj 1204 Word Puzzles (ac自动机))