AC自动机的应用,第一次做ac自动机,磕磕碰碰做了一整天,之前对于AC自动机的原理就想了好几个星期,一直没想透彻,失配函数还行,就是那个匹配过程不是很透彻,昨天又想了想,突然感觉理解了,但今天发现有些细节还是没搞透彻,唉╮(╯▽╰)╭ 。
思路就是枚举每个方向的字符串通过利用AC自动机进行匹配,610ms水过
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 const int maxn=1000+10; 7 char s[maxn][maxn]; 8 int ch[maxn*300][26],val[maxn*300],f[maxn*300],location[maxn][2],len[maxn],rd[maxn],last[maxn*300]; 9 int dir[8][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}}; 10 char dm[8]={'A','B','C','D','E','F','G','H'}; 11 int l,c,w,tot; 12 void Insert(char * ts,int x) 13 { 14 int i,len=strlen(ts),u=0,loc; 15 for(i=0;i<len;i++) 16 { 17 loc=ts[i]-'A'; 18 if(!ch[u][loc]) 19 ch[u][loc]=++tot; 20 u=ch[u][loc]; 21 } 22 val[u]=x; 23 } 24 void getFail() 25 { 26 queue<int> q; 27 int i,u; 28 f[0]=0; 29 for(i=0;i<26;i++) 30 { 31 u=ch[0][i]; 32 if(u) 33 { 34 f[u]=0; 35 last[u]=0; 36 q.push(u); 37 } 38 } 39 int fr,j; 40 while(!q.empty()) 41 { 42 fr=q.front();q.pop(); 43 for(i=0;i<26;i++) 44 { 45 u=ch[fr][i]; 46 if(!u) 47 { 48 ch[fr][i]=ch[f[fr]][i];//意思就是说失配了 49 continue; 50 } 51 q.push(u); 52 j=f[fr]; 53 while(j&&!ch[fr][i]) j=f[fr]; 54 f[u]=ch[j][i]; 55 last[u]=val[f[u]]?f[u]:last[f[u]]; 56 } 57 } 58 } 59 void getL(int j,int x,int y,int d) 60 { 61 if(j) 62 { 63 int t=val[j]; 64 rd[t]=d; 65 location[t][0]=x-(len[t]-1)*dir[d][0]; 66 location[t][1]=y-(len[t]-1)*dir[d][1]; 67 getL(last[j],x,y,d); 68 } 69 } 70 void solve(int x,int y,int d) 71 { 72 int tc,j=0; 73 for(;x>=0&&x<l&&y>=0&&y<c;x+=dir[d][0],y+=dir[d][1]) 74 { 75 tc=s[x][y]-'A'; 76 j=ch[j][tc]; 77 if(val[j]) getL(j,x,y,d); 78 else if(last[j]) getL(last[j],x,y,d); 79 } 80 } 81 int main() 82 { 83 char ts[maxn]; 84 scanf("%d%d%d",&l,&c,&w); 85 int i; 86 for(i=0;i<l;i++) scanf("%s",s[i]); 87 for(i=1;i<=w;i++) 88 { 89 scanf("%s",ts); 90 len[i]=strlen(ts); 91 Insert(ts,i); 92 } 93 getFail(); 94 for(i=0;i<l;i++) 95 { 96 solve(i,0,1); 97 solve(i,0,2); 98 solve(i,0,3); 99 solve(i,c-1,5); 100 solve(i,c-1,6); 101 solve(i,c-1,7); 102 } 103 for(i=0;i<c;i++) 104 { 105 solve(0,i,3); 106 solve(0,i,4); 107 solve(0,i,5); 108 solve(l-1,i,0); 109 solve(l-1,i,1); 110 solve(l-1,i,7); 111 } 112 for(i=1;i<=w;i++) 113 printf("%d %d %c\n",location[i][0],location[i][1],dm[rd[i]]); 114 return 0; 115 }
---恢复内容结束---