POJ1204 Word Puzzles(AC自动机)

给一个L*C字符矩阵和W个字符串,问那些字符串出现在矩阵的位置,横竖斜八个向。

就是个多模式匹配的问题,直接AC自动机搞了,枚举字符矩阵八个方向的所有字符串构成主串,然后在W个模式串构造的AC自动机上跑。

另外,temp指针的那个找遗漏后缀的过程执行时标记一下,下一次再到这个结点就不需要再进行一次temp的过程,这样的时间复杂度就是O(W个模式串总长+LC)。

一开始还想8个方向分别计算坐标= =写第二个方向懒得写了,然后就忽然想到可以一开始构造主串时就存坐标。。最后代码很是挺长的。。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 using namespace std;
  5 #define MAXN 111111
  6 int tn,ch[MAXN][26],flag[MAXN],fail[MAXN],len[MAXN];
  7 void insert(char *s,int k,int l){
  8     int x=0;
  9     for(int i=0; s[i]; ++i){
 10         int y=s[i]-'A';
 11         if(ch[x][y]==0) ch[x][y]=++tn;
 12         x=ch[x][y];
 13     }
 14     flag[x]=k;
 15     len[x]=l;
 16 }
 17 void getFail(){
 18     memset(fail,0,sizeof(fail));
 19     queue<int> que;
 20     for(int i=0; i<26; ++i){
 21         if(ch[0][i]) que.push(ch[0][i]);
 22     }
 23     while(!que.empty()){
 24         int x=que.front(); que.pop();
 25         for(int i=0; i<26; ++i){
 26             if(ch[x][i]) que.push(ch[x][i]),fail[ch[x][i]]=ch[fail[x]][i];
 27             else ch[x][i]=ch[fail[x]][i]; 
 28         }
 29     }
 30 }
 31 
 32 int n,m;
 33 int ansx[1111],ansy[1111],anso[1111];
 34 char str[1111]; int sx[1111],sy[1111];
 35 void match(char o){
 36     int x=0;
 37     for(int i=0; str[i]; ++i){
 38         int y=str[i]-'A';
 39         x=ch[x][y];
 40         int tmp=x;
 41         while(flag[tmp] && tmp){
 42             if(flag[tmp]>0){
 43                 int &idx=flag[tmp];
 44                 ansx[idx]=sx[i-len[tmp]+1];
 45                 ansy[idx]=sy[i-len[tmp]+1];
 46                 anso[idx]=o;
 47                 idx=-1;
 48             }else if(flag[tmp]==-1) break;
 49             tmp=fail[tmp];
 50         }
 51     }
 52 }
 53 char map[1111][11111];
 54 int main(){
 55     int w;
 56     scanf("%d%d%d",&n,&m,&w);
 57     for(int i=0; i<n; ++i) scanf("%s",map[i]);
 58     for(int i=1; i<=w; ++i){
 59         scanf("%s",str);
 60         insert(str,i,strlen(str));
 61     }
 62     getFail();
 63     int sn;
 64     //zero
 65     for(int i=0; i<m; ++i){
 66         for(int j=0; j<n; ++j){
 67             sx[n-j-1]=j; sy[n-j-1]=i;
 68             str[n-j-1]=map[j][i];
 69         }
 70         str[n]=0;
 71         match('A');
 72     }
 73     //one
 74     for(int i=0; i<n; ++i){
 75         int x=i,y=0,sn=0;
 76         while(x>=0 && y<m){
 77             sx[sn]=x; sy[sn]=y;
 78             str[sn++]=map[x][y];
 79             --x; ++y;
 80         }
 81         str[sn]=0;
 82         match('B');
 83     }
 84     for(int i=1; i<m; ++i){
 85         int x=n-1,y=i,sn=0;
 86         while(x>=0 && y<m){
 87             sx[sn]=x; sy[sn]=y;
 88             str[sn++]=map[x][y];
 89             --x; ++y;
 90         }
 91         str[sn]=0;
 92         match('B');
 93     }
 94     //two
 95     for(int i=0; i<n; ++i){
 96         for(int j=0; j<m; ++j){
 97             sx[j]=i; sy[j]=j;
 98             str[j]=map[i][j];
 99         }
100         str[m]=0;
101         match('C');
102     }
103     //three
104     for(int i=0; i<m; ++i){
105         int x=0,y=i,sn=0;
106         while(x<n && y<m){
107             sx[sn]=x; sy[sn]=y;
108             str[sn++]=map[x][y];
109             ++x; ++y;
110         }
111         str[sn]=0;
112         match('D');
113     }
114     for(int i=1; i<n; ++i){
115         int x=i,y=0,sn=0;
116         while(x<n && y<m){
117             sx[sn]=x; sy[sn]=y;
118             str[sn++]=map[x][y];
119             ++x; ++y;
120         }
121         str[sn]=0;
122         match('D');
123     }
124     //four
125     for(int i=0; i<m; ++i){
126         for(int j=0; j<n; ++j){
127             sx[j]=j; sy[j]=i;
128             str[j]=map[j][i];
129         }
130         str[n]=0;
131         match('E');
132     }
133     //five
134     for(int i=0; i<m; ++i){
135         int x=0,y=i,sn=0;
136         while(x<n && y>=0){
137             sx[sn]=x; sy[sn]=y;
138             str[sn++]=map[x][y];
139             ++x; --y;
140         }
141         str[sn]=0;
142         match('F');
143     }
144     for(int i=1; i<n; ++i){
145         int x=i,y=m-1,sn=0;
146         while(x<n && y>=0){
147             sx[sn]=x; sy[sn]=y;
148             str[sn++]=map[x][y];
149             ++x; --y;
150         }
151         str[sn]=0;
152         match('F');
153     }
154     //six
155     for(int i=0; i<n; ++i){
156         for(int j=0; j<m; ++j){
157             sx[m-j-1]=i; sy[m-j-1]=j;
158             str[m-j-1]=map[i][j];
159         }
160         str[m]=0;
161         match('G');
162     }
163     //seven
164     for(int i=0; i<m; ++i){
165         int x=n-1,y=i,sn=0;
166         while(x>=0 && y>=0){
167             sx[sn]=x; sy[sn]=y;
168             str[sn++]=map[x][y];
169             --x; --y;
170         }
171         str[sn]=0;
172         match('H');
173     }
174     for(int i=0; i<n-1; ++i){
175         int x=i,y=m-1,sn=0;
176         while(x>=0 && y>=0){
177             sx[sn]=x; sy[sn]=y;
178             str[sn++]=map[x][y];
179             --x; --y;
180         }
181         str[sn]=0;
182         match('H');
183     }
184     for(int i=1; i<=w; ++i){
185         printf("%d %d %c
",ansx[i],ansy[i],anso[i]);
186     }
187     return 0;
188 }
原文地址:https://www.cnblogs.com/WABoss/p/5244528.html