poj 1204 AC自动机

来源:互联网 发布:淘宝卖家提前收款 编辑:程序博客网 时间:2024/05/01 10:34

AC自动机的经典题

可以使用一个小技巧,将要查找的单词反过来建自动机,这样便于记录首字母的位置。

#include <iostream>using namespace std;const int maxn=1005,maxl=200000;const int dx[9]={0,-1,-1,0,1,1,1,0,-1};const int dy[9]={0,0,1,1,1,0,-1,-1,-1};struct node{       node* ch[26];       node* fail;       int no;            };node* root=new node;char s[maxn],a[maxn][maxn];int gx[maxn],gy[maxn],ansx[maxn],ansy[maxn],ansd[maxn];int i,j,k,dir,n,m,kk;void ins(char* s,int x){     node* now=root;     int i,j,k,len=strlen(s);     for (i=len-1;i>=0;i--)     {         k=s[i]-'A';         if (now->ch[k]!=0)             now=now->ch[k];         else          {              now->ch[k]=new node;              now=now->ch[k];              for (int j=0;j<26;j++)                  now->ch[j]=0;              now->no=-1;now->fail=root;         }     }     now->no=x;}node* q[maxl];void build(){     int i,h=0,r=1;     node *now,*ff;     root->fail=0;     q[++h]=root;     while (h<=r)     {           now=q[h++];           for (i=0;i<26;i++)               if (now->ch[i]!=0)               {                  q[++r]=now->ch[i];                  for (ff=now->fail;ff!=0;ff=ff->fail)                      if (ff->ch[i]!=0)                      {                         now->ch[i]->fail=ff->ch[i];                         break;                      }               }     }}void match(char* s){     int i,j,k,len=strlen(s);     node* now=root,*tmp;     for (i=0;i<len;i++)     {         k=s[i]-'A';         while (now->ch[k]==0 && now!=root)               now=now->fail;         if (now->ch[k]==0) continue;         now=now->ch[k];         tmp=now;         while (tmp!=0 && tmp->no!=-1)         {               ansx[tmp->no]=gx[i];               ansy[tmp->no]=gy[i];               ansd[tmp->no]=dir;               tmp->no=-1;               tmp=tmp->fail;         }     }}         void make(int x,int y,int dir){     int len=0;     while (x>=0 && x<n && y>=0 && y<m)       {           s[len]=a[x][y];           gx[len]=x;gy[len]=y;           x+=dx[dir];y+=dy[dir];           len++;     }}               int main(){    freopen("pin.txt","r",stdin);    freopen("pou.txt","w",stdout);    cin >> n >> m >> kk;    for (i=0;i<26;i++)        root->ch[i]=0;    root->no=-1;    getchar();    for (i=0;i<n;i++)    {        for (j=0;j<m;j++)            a[i][j]=getchar();        getchar();    }    for (i=0;i<kk;i++)    {        cin >> s;        ins(s,i);    }    build();    for (i=0;i<n;i++)        for (j=0;j<m;j++)            if (i==0 || i==n-1 || j==0 || j==m-1)            for (k=1;k<=8;k++)            {                if (k==4) make(i,j,8);                else make(i,j,(k+4)%8);                dir=k;                match(s);            }    for (i=0;i<kk;i++)        printf("%d %d %c\n",ansx[i],ansy[i],ansd[i]+'A'-1);    return 0;}

原创粉丝点击