poj1204

一开始做这道题没什么头绪,那时只会写Trie,ac自动机不怎么懂。后来在discuss里看到要用AC自动机做。

先把要查询的字符串添加进Trie图里,建完自动机后再从矩形四周八个方向依次查询,结果放在数组里。

  1 #include<cstdio>
  2 #include<string.h>
  3 #include<iostream>
  4 #include<queue>
  5 using namespace std;
  6 const int maxn=1001;
  7 char g[maxn][maxn],T[maxn][maxn],str[maxn];
  8 int ch[maxn*maxn][26],val[maxn*maxn],f[maxn*maxn],last[maxn*maxn],vis[maxn];
  9 int L,C,W,top,ans[maxn][4];
 10 int dir[][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
 11 void init()
 12 {
 13     top=1;
 14     memset(ch[0],0,sizeof(ch[0]));
 15     memset(ans,0,sizeof(ans));
 16 }
 17 int idx(char c)
 18 {
 19     return c-'A';
 20 }
 21 void insert(char *s,int op)
 22 {
 23     int u=0,n=strlen(s),c;
 24     for(int i=0;i<n;i++)
 25     {
 26         c=idx(s[i]);
 27         if(ch[u][c]==0)
 28         {
 29             memset(ch[top],0,sizeof(ch[top]));
 30             val[top]=0;
 31             ch[u][c]=top++;
 32         }
 33         u=ch[u][c];
 34     }
 35     val[u]=op+1;
 36     //printf("val=%d\n",val[u]);
 37 }
 38 
 39 void getfail()
 40 {
 41     queue<int> q;
 42     f[0]=0;
 43     for(int c=0;c<26;c++)
 44     {
 45         int u=ch[0][c];
 46         if(u){f[u]=0;q.push(u);last[u]=0;}
 47     }
 48     while(!q.empty())
 49     {
 50         int r=q.front();q.pop();
 51         for(int c=0;c<26;c++)
 52         {
 53             int u=ch[r][c];
 54             if(!u) continue;
 55             q.push(u);
 56             int v=f[r];
 57             while(v&&!ch[v][c]) v=f[v];
 58             f[u]=ch[v][c];
 59             last[u]=val[f[u]]?f[u]:last[f[u]];
 60         }
 61     }
 62 }
 63 
 64 bool ok(int x,int y)
 65 {
 66     return (x>=0&&x<L&&y>=0&&y<C);
 67 }
 68 
 69 void print(int j,int pos,int x,int y,int d)
 70 {
 71     //printf("j=%d d=%d x=%d y=%d ",j,d,x,y);
 72     int n=strlen(T[j]);
 73     int i;
 74     //printf("%d")
 75     n=pos-n;
 76     //printf("n=%d pos=%d ",n,pos);
 77     int nx=x,ny=y;
 78     for(i=0;i<=n;i++)
 79     {
 80         nx+=dir[d][0];
 81         ny+=dir[d][1];
 82     }
 83     //printf("nx=%d ny=%d\n",nx,ny);
 84     ans[j][0]=nx;
 85     ans[j][1]=ny;
 86     ans[j][2]=d;
 87 }
 88 void find(char *T,int x,int y,int d)
 89 {
 90     int n=strlen(T);
 91     int i,j=0;
 92     for(i=0;i<n;i++)
 93     {
 94         int c=T[i]-'A';
 95         while(j&&!ch[j][c]) j=f[j];
 96         j=ch[j][c];
 97         if(val[j]) print(val[j]-1,i,x,y,d);
 98         else if(last[j]) print(val[last[j]]-1,i,x,y,d);
 99     }
100 }
101 void make(int x,int y,int d)
102 {
103     int nx=x,ny=y,j=0;
104     while(ok(nx,ny))
105     {
106         str[j++]=g[nx][ny];
107         nx+=dir[d][0];
108         ny+=dir[d][1];
109     }
110     str[j]='\0';
111     find(str,x,y,d);
112 }
113 void work()
114 {
115     getfail();
116     memset(vis,0,sizeof(vis));
117     int i,j;
118     for(i=0;i<L;i++)
119     {
120         for(j=0;j<8;j++)
121         {
122             make(i,0,j);
123             make(i,C-1,j);
124         }
125     }
126     for(i=0;i<C;i++)
127     {
128         for(j=0;j<8;j++)
129         {
130             make(0,i,j);
131             make(L-1,i,j);
132         }
133     }
134 }
135 
136 
137 int main()
138 {
139     //freopen("test.txt","r",stdin);
140     scanf("%d%d%d",&L,&C,&W);
141     int i,j;
142     getchar();
143     init();
144     for(i=0;i<L;i++)
145     scanf("%s",g[i]);
146     for(i=0;i<W;i++)
147     {
148         scanf("%s",T[i]);
149         insert(T[i],i);
150     }
151     work();
152     for(i=0;i<W;i++)
153     {
154         printf("%d %d %c\n",ans[i][0],ans[i][1],ans[i][2]+'A');
155     }
156     return 0;
157 }
View Code

 

posted @ 2013-05-22 20:55  longlongago  Views(127)  Comments(0Edit  收藏  举报