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 }