poj 1204 AC自动机

来源:互联网 发布:淘宝连接怎样微博推广 编辑:程序博客网 时间:2024/05/01 05:57

最直观的想法是8*(n*n)*n*n暴力

由于在表里面要朝8个方向走,不能在上面建自动机,所以要在pattern建自动机

建好后,在原表上朝8个方向走遍历整个表,这时候复杂度是8*n*n

比较慢,但觉得比较直观

#include <iostream>#include <cstring>#include <cstdio>using namespace std;#define sigma_size 26#define N 1010struct Node{    int idx;    Node *fail;    Node* nxt[sigma_size];    Node()    {        idx=0;fail=NULL;        memset(nxt,NULL,sizeof(nxt));    }};void _insert(char *s,Node *root,int idx){    for(int i=0;s[i]!='\0';++i)    {        if(root->nxt[s[i]-'A']==NULL)            root->nxt[s[i]-'A']=new Node();        root=root->nxt[s[i]-'A'];    }    root->idx=idx;}Node*q[1001000];void getfail(Node *root){    int head=0,tail=0;    q[tail++]=root;    root->fail=NULL;    while(head<tail)    {        Node *u=q[head++];        for(int i=0;i<sigma_size;++i)            if(u->nxt[i])        {            if(u==root)                u->nxt[i]->fail=root;            else            {                Node *p=u->fail;                while(p!=NULL&&p->nxt[i]==NULL) p=p->fail;                u->nxt[i]->fail= p==NULL?root:p->nxt[i];            }            q[tail++]=u->nxt[i];        }    }}int dir[8][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};int ansx[N],ansy[N],ansz[N];char mat[N][N],temp[N];char T[N][N];int L,C,W;Node *root;void dfs(int row,int col,int d,Node *u){    //if(u->idx==1||u->idx==2)        //cout<<'d';    if(u->idx)    {        /*ansx[u->idx]=row;        ansy[u->idx]=col;        ansz[u->idx]=d;*/        Node *p=u;        while(p!=NULL)        {            if(p->idx)            {                ansx[p->idx]=row;                ansy[p->idx]=col;                ansz[p->idx]=d;            }            p=p->fail;        }    }    if(row>=0&&row<L&&col>=0&&col<C);    else return;    if(u->nxt[mat[row][col]-'A'])        dfs(row+dir[d][0],col+dir[d][1],d,u->nxt[mat[row][col]-'A']);    else {            if(u==root)                dfs(row+dir[d][0],col+dir[d][1],d,u);            else dfs(row,col,d,u->fail);    }}int main (){    while(scanf("%d%d%d",&L,&C,&W)!=EOF)    {        for(int i=0;i<L;++i)            scanf("%s",mat[i]);        root=new Node();        for(int i=1;i<=W;++i)        {            scanf("%s",T[i]);            _insert(T[i],root,i);        }        getfail(root);        for(int i=0;i<L;++i)            for(int j=0;j<C;++j)            if(i==0||i==L-1||j==0||j==C-1)            {                for(int d=0;d<8;++d)                    dfs(i,j,d,root);            }        for(int i=1;i<=W;++i)        {            int rev=(ansz[i]+4)%8;            int tt=strlen(T[i]);            for(int j=1;j<=tt;++j)            {                ansx[i]+=dir[rev][0];                ansy[i]+=dir[rev][1];            }            ansz[i]+='A';            printf("%d %d %c\n",ansx[i],ansy[i],ansz[i]);        }    }    return 0;}