Word Puzzles [POJ 1204]

View Code
//POJ 1204
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

#define ROOT 0
#define debug puts("wrong")
const int MM=1010;
const int MAX_NODE=100100;
const int CHI=26;
int L,C,W;
int cnt;
int len[MM];
int ansx[MM], ansy[MM], ansk[MM];
char text[MAX_NODE];
char ch[MM][MM];

char dir[8]={'C','D','E','F','G','H','A','B'};
int dx[8]={0,1,1,1,0,-1,-1,-1};
int dy[8]={1,1,0,-1,-1,-1,0,1};

struct ACtree {
     int size;
     int hash[300];
     int val[MAX_NODE];
     int fail[MAX_NODE];
     int SQ[MAX_NODE];
     int chd[MAX_NODE][CHI];
     void get_hash() {
         int i,j,k;
         for(i=0;i<CHI;i++) 
             hash[i+'A']=i;
     }
     void init() {
         size=fail[0]=0;
         memset(val,0,sizeof(val));
         memset(chd[0],0,sizeof(chd));
     }
     void insert(char *str,int k) {
          int i,j,id,p=ROOT;
          for(i=0;str[i];i++) {
              id=hash[str[i]];
              if(!chd[p][id]) {
                  chd[p][id]=++size;
                  memset(chd[size],0,sizeof(chd[size]));
              }
              p=chd[p][id];
          }
          val[p]=k;
     }
     void build() {
          int i,j,k,id,p=ROOT,r,v;
          int qhead,qtail;
          qhead=qtail=0;
          for(i=0;i<CHI;i++) {
              if(chd[p][i]) {
                  SQ[qtail++]=chd[p][i];
                  fail[chd[p][i]]=ROOT;
              }
          }
          while(qhead!=qtail) {
              r=SQ[qhead++];
              for(i=0;i<CHI;i++) {
                  v=chd[r][i]; 
                  if(v) SQ[qtail++]=v,fail[v]=chd[fail[r]][i];
                  else chd[r][i]=chd[fail[r]][i];
              }
          }
     }
     void solve(char *str,int xx,int yy,int dd) {
          int i,j,k,id,tt,p=ROOT,v;
          for(i=0;str[i];i++) {
                id=hash[str[i]];
                while(p&&!chd[p][id]) p=fail[p];
                p=chd[p][id]; v=val[p];
                if(v) { 
                tt=i-len[v];
                ansx[v]=xx+tt*dx[dd],ansy[v]=yy+tt*dy[dd],ansk[v]=dd;
//                 printf("%d %d %d %d %d\n",i,v,xx,yy,dd);  
                }
          }     
     }
}AC;

bool ok(int x,int y) {
     if(x<0||x>=L||y<0||y>=C) return false;
     else return true;
}

void get_data() {
     int i,j,k,xx,yy;
     for(i=0;i<L;i++) {
         scanf("%s",ch[i]);
     }
}

void solve() {
    int i,j,k,xx,yy,dd;
    char str[MM];
    AC.init();
    for(i=1;i<=W;i++) {
          scanf("%s",str);
          len[i]=strlen(str)-1;
          AC.insert(str,i);
    }
    AC.build();
         for(j=0;j<C;j++) {
             for(k=0;k<8;k++) {
                  xx=0; yy=j; dd=k; cnt=0;
                  while(ok(xx,yy)) {
                      text[cnt++]=ch[xx][yy];
                      xx+=dx[k];  yy+=dy[k];
                  }
                  text[cnt]='\0';
                  AC.solve(text,0,j,dd);
             }
         }
         for(j=0;j<C;j++) {
             for(k=0;k<8;k++) {
                  xx=L-1; yy=j; dd=k; cnt=0;
                  while(ok(xx,yy)) {
                      text[cnt++]=ch[xx][yy];
                      xx+=dx[k];  yy+=dy[k];
                  }
                  text[cnt]='\0';
                  AC.solve(text,L-1,j,dd);
             }
         }
          for(i=0;i<L;i++) {
             for(k=0;k<8;k++) {
                  xx=i; yy=0; dd=k; cnt=0;
                  while(ok(xx,yy)) {
                      text[cnt++]=ch[xx][yy];
                      xx+=dx[k];  yy+=dy[k];
                  }
                  text[cnt]='\0';
                  AC.solve(text,i,0,dd);
             }
     }
      for(i=0;i<L;i++) {
             for(k=0;k<8;k++) {
                  xx=i; yy=C-1; dd=k; cnt=0;
                  while(ok(xx,yy)) {
                      text[cnt++]=ch[xx][yy];
                      xx+=dx[k];  yy+=dy[k];
                  }
                  text[cnt]='\0';
                  AC.solve(text,i,C-1,dd);
             }
     }
     for(i=1;i<=W;i++) printf("%d %d %c\n",ansx[i],ansy[i],dir[ansk[i]]); 
}

int main() {
    AC.get_hash();
    while(scanf("%d%d%d",&L,&C,&W)!=EOF) get_data(),solve();
    return 0;
}
原文地址:https://www.cnblogs.com/zhang1107/p/2949620.html