1. 程式人生 > >POJ1204:Word Puzzles——題解

POJ1204:Word Puzzles——題解

枚舉 ++ har 循環 處理 ons namespace iostream for

http://poj.org/problem?id=1204

題目大意:給一個字母表,求一些字符串的開端第一次出現的位置和字符串的方向(字符串可以按照八個方向放在字母表中可匹配的位置)

————————————————————————————————

一定是AC自動機,而且我們不可能對二位字母表AC一下,所以我們要把待匹配串AC一下,然後枚舉字母表的起點(不要枚舉多了),ACcheck一下就好了,蠻裸的。

為了保證最小序,需要對枚舉順序改一下,具體循環方法我piao了這位大佬的博客。

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const
int L=1001; const int C=1001; const int M=1501; const int W=1001; int dx[8]={0,1,0,-1,1,1,-1,-1}; int dy[8]={1,0,-1,0,-1,1,1,-1}; char dir[8]={C,E,G,A,F,D,B,H}; struct trie{ int ed; int a[26]; int fail; int l; }tree[C*L]={0}; char mp[L][C],s[M]; int ans[W][3]; bool
vis[W]; int cnt=0,l,c,w; inline void insert(int k){ int now=0; int len=strlen(s); for(int i=0;i<len;i++){ int t=s[i]-A; if(!tree[now].a[t]){ cnt++; tree[now].a[t]=cnt; } now=tree[now].a[t]; } tree[now].ed=k; tree[now].l=len; return; } int q[C*L]; void getfail(){ int r=0; //以下是對第一層的特殊處理 for(int i=0;i<26;i++){ if(tree[0].a[i]!=0){ tree[tree[0].a[i]].fail=0; r++;q[r]=tree[0].a[i]; } } for(int l=1;l<=r;l++){ int u=q[l]; for(int i=0;i<26;i++){ if(tree[u].a[i]!=0){ tree[tree[u].a[i]].fail=tree[tree[u].fail].a[i]; r++;q[r]=tree[u].a[i]; }else{ tree[u].a[i]=tree[tree[u].fail].a[i]; } } } return; } void check(int x,int y,int d){ int now=0; while(x>=0&&x<l&&y>=0&&y<c){ int t=mp[x][y]-A; now=tree[now].a[t]; for(int j=now;j;j=tree[j].fail){ int k=tree[j].ed; int len=tree[j].l-1; if(k&&!vis[k]){ vis[k]=1; ans[k][0]=x-dx[d]*len; ans[k][1]=y-dy[d]*len; ans[k][2]=d; } } x+=dx[d]; y+=dy[d]; } return; } int main(){ cin>>l>>c>>w; for(int i=0;i<l;i++){ cin>>mp[i]; } for(int i=1;i<=w;i++){ cin>>s; insert(i); } getfail(); for(int i=0;i<l;i++) for(int j=0;j<8;j++) check(i,0,j); for(int i=0;i<l;i++) for(int j=0;j<8;j++) check(i,c-1,j); for(int i=0;i<c;i++) for(int j=0;j<8;j++) check(0,i,j); for(int i=0;i<c;i++) for(int j=0;j<8;j++) check(l-1,i,j); for(int i=1;i<=w;i++) printf("%d %d %c\n",ans[i][0],ans[i][1],dir[ans[i][2]]); return 0; }

POJ1204:Word Puzzles——題解