码迷,mamicode.com
首页 > 其他好文 > 详细

[poj] 1204 Word Puzzles || AC自动机

时间:2017-12-06 14:18:16      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:http   bfs   输出   ++   不能   pre   ble   +=   names   

原题

给个X*Y的字符串矩阵,W个询问,对每个询问输出这个串出现的位置及方向,共有8个方向,顺时针开始分别用A~H表示

AC自动机的板子题。
对于待匹配串建一个自动机,然后从矩阵的四周分别沿八个方向跑,找到一个串的时候就记录答案,但不能退出。

另:方向要找好啊!!

#include<cstdio>
#include<cstring>
#define N 1010
using namespace std;
int x,y,n,ansx[N],ansy[N],d[N],l[N];
//int dx[10]={0,0,1,1,1,0,-1,-1,-1},dy[10]={0,1,1,0,-1,-1,-1,0,1};
int dx[10]={0,-1,-1,0,1,1,1,0,-1},dy[10]={0,0,1,1,1,0,-1,-1,-1};
char t[N][N],s[N],r[10]=" ABCDEFGH";
struct hhh
{
    int data;
    hhh *child[26],*fail;
    hhh()
    {
        fail=NULL;
        data=0;
        for (int i=0;i<26;i++) child[i]=NULL;
    }
};
hhh *root=new hhh;
hhh *now,*tmp;
hhh* q[100*1000+10];

void add(int x)
{
    now=root;
    for (int i=1;i<=l[x];i++)
    {
    if (now->child[s[i]-'A']==NULL)
        now->child[s[i]-'A']=new hhh;
    now=now->child[s[i]-'A'];
    }
    now->data=x;
}

void bfs()
{
    int l=0,r=0;
    root->fail=root;
     for (int i=0;i<26;i++)
    {
    if (root->child[i]==NULL)
        root->child[i]=root;
    else
        root->child[i]->fail=root,q[r++]=(root->child[i]);
    }
    while (r!=l)
    {
    hhh* nw=q[l++];
    for (int i=0;i<26;i++)
    {
        if (nw->child[i])
        {
        now=nw->child[i];
        if (now!=root) q[r++]=now;
        if (now->fail==NULL) now->fail=nw->fail->child[i];
        }
        else nw->child[i]=nw->fail->child[i];
        if (nw->data==0 && nw->fail->data)
        nw->data=nw->fail->data;
    }
    }
}

void find(int a,int b,int i)
{
    now=root;
    while (1)
    {
    if (a<=0 || a>x) break;
    if (b<=0 || b>y) break;
    now=now->child[t[a][b]-'A'];
    tmp=now;
    while (tmp->data)
    {
        int tp=tmp->data;
        ansx[tp]=a-dx[i]*(l[tp]-1);
        ansy[tp]=b-dy[i]*(l[tp]-1);
        d[tp]=i;
        tmp=tmp->fail;
    }
    a+=dx[i];
    b+=dy[i];
    }
}

int main()
{
    scanf("%d%d%d",&x,&y,&n);
    for (int i=1;i<=x;i++)
    scanf("%s",t[i]+1);
    for (int i=1;i<=n;i++)
    {
    scanf("%s",s+1);
    l[i]=strlen(s+1);
    add(i);
    }
    bfs();
    for (int i=1;i<=8;i++)
    {
    for (int j=1;j<=x;j++)
    {
        find(j,1,i);
        find(j,y,i);
    }
    for (int j=1;j<=y;j++)
    {
        find(1,j,i);
        find(x,j,i);
    }
    }
    for (int i=1;i<=n;i++)
    printf("%d %d %c\n",ansx[i]-1,ansy[i]-1,r[d[i]]);
    return 0;
}

[poj] 1204 Word Puzzles || AC自动机

标签:http   bfs   输出   ++   不能   pre   ble   +=   names   

原文地址:http://www.cnblogs.com/mrha/p/7992162.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!