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\n",ansx[i],ansy[i],anso[i]); 186 } 187 return 0; 188 }