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

AC自动机

代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<algorithm>

#define LL long long

using namespace std;

const int INF=0x3f3f3f3f;
const int N=1005;
const int M=1000005;
const int K=26;
struct nodeTrie
{
    int v;
    int level;
    int fail;
    int next[K];
    void initialize()
    {
        v=0;
        level=0;
        fail=-1;
        memset(next,-1,sizeof(next));
    }
}trie[M];
int cnt,root;
char graph[N][N];
int X[]={-1,-1,0,1,1,1,0,-1};
int Y[]={0,1,1,1,0,-1,-1,-1};
char s[N];
int outx[N],outy[N],outd[N],dx[N],dy[N];
int getNewNode()
{
    ++cnt;
    trie[cnt].initialize();
    return cnt;
}
void addWord(int p,char *s,int k)
{
    if(s[0]=='\0') return ;
    for(int i=0;s[i]!='\0';++i)
    {
        if(trie[p].next[s[i]-'A']==-1)
        trie[p].next[s[i]-'A']=getNewNode();
        p=trie[p].next[s[i]-'A'];
        trie[p].level=i;
        //cout<<s[i]<<" "<<trie[p].level<<endl;
    }
    (trie[p].v)=k;
}
void init(int n,int m,int w)
{
    cnt=-1;
    root=getNewNode();
    for(int i=0;i<n;++i)
    gets(graph[i]);
    for(int i=1;i<=w;++i)
    {
        gets(s);
        addWord(root,s,i);
    }
}
void bfs(int p)
{
    trie[p].fail=root;
    queue<int>qt;
    qt.push(p);
    while(!qt.empty())
    {
        int y;
        int x=qt.front();qt.pop();
        for(int i=0;i<K;++i)
        if(trie[x].next[i]!=-1)
        {
            qt.push(trie[x].next[i]);
            if(x==root)
            {trie[trie[x].next[i]].fail=root;continue;}
            y=trie[x].fail;
            while(y!=root&&trie[y].next[i]==-1)
            y=trie[y].fail;
            if(trie[y].next[i]!=-1)
            trie[trie[x].next[i]].fail=trie[y].next[i];
            else
            trie[trie[x].next[i]].fail=root;
        }
    }
}
void match(int p,char *s,int d)
{
    int l=0;
    while(s[l]!='\0')
    {
        while(trie[p].next[s[l]-'A']==-1&&p!=root)
        p=trie[p].fail;
        if(trie[p].next[s[l]-'A']!=-1)
        p=trie[p].next[s[l]-'A'];
        int fp=p;
        while(fp!=root)
        {
            if(trie[fp].v==-1)
            break;
            if(trie[fp].v>0)
            {
                outx[trie[fp].v]=dx[l-trie[fp].level];
                outy[trie[fp].v]=dy[l-trie[fp].level];
                outd[trie[fp].v]=d;
            }
            trie[fp].v=-1;
            fp=trie[fp].fail;
        }
        ++l;
    }
}
void getSentence(int n,int m,int x1,int y1,int k)
{
    int len=0;
    for(int x=x1,y=y1;x>=0&&x<n&&y>=0&&y<m;x+=X[k],y+=Y[k])
    {
        s[len]=graph[x][y];
        dx[len]=x;
        dy[len]=y;
        ++len;
    }
    s[len]='\0';
    match(root,s,k);
}
int main()
{
    //freopen("data.in","r",stdin);
    int n,m,w;
    while(scanf("%d %d %d ",&n,&m,&w)!=EOF)
    {
        init(n,m,w);
        bfs(root);
        for(int i=0;i<n;++i)
        {
            getSentence(n,m,i,0,1);
            getSentence(n,m,i,0,2);
            getSentence(n,m,i,0,3);
            getSentence(n,m,i,m-1,5);
            getSentence(n,m,i,m-1,6);
            getSentence(n,m,i,m-1,7);
        }
        for(int j=0;j<m;++j)
        {
            getSentence(n,m,0,j,3);
            getSentence(n,m,0,j,4);
            getSentence(n,m,0,j,5);
            getSentence(n,m,n-1,j,0);
            getSentence(n,m,n-1,j,1);
            getSentence(n,m,n-1,j,7);
        }
        for(int i=1;i<=w;++i)
        printf("%d %d %c\n",outx[i],outy[i],outd[i]+'A');
    }
    return 0;
}

  

posted on 2013-03-23 07:56  夜->  阅读(184)  评论(0编辑  收藏  举报