poj 1204 Word Puzzles

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;

}

  

你可能感兴趣的:(word)