1. 程式人生 > >POJ1204 Word Puzzles

POJ1204 Word Puzzles

匹配 math ins set ack sca 輸入 lse getch

嘟嘟嘟

翻譯洛谷有,但輸入格式好像不太一樣,註意一下。

這題我看了5分鐘才把題看懂,知道是有關AC自動機的,然而就是想不出來。

我一直覺得應該把這張圖建一個trie樹,畢竟圖作為主串,然後看模式串是否出現在主串裏。

然而實際上是模式串建trie樹。

然後題中說要判斷8個方向是否有模式串出現,那麽就把圖中8個方向形成的字符串都放到AC自動機上跑一下。我剛開始以為會超時,但復雜度最多為O(8 * n2),只有8e6,而AC自動機是線性的,所以TLE不了。

關於遍歷八個方向上的字符串,寫起來得動動腦子,可以聯想到bfs或dfs跑圖的時候用到的方向數組。

然後有因為AC自動機找到的匹配點是模式串的末尾,所以我們還要在這個方向上減去模式串的長度。

然後就是AC自動機的板子了。

技術分享圖片
  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<cstring>
  6 #include<cstdlib>
  7 #include<cctype>
  8 #include<stack>
  9 #include<queue>
 10 #include<vector>
 11 using
namespace std; 12 #define enter puts("") 13 #define space putchar(‘ ‘) 14 #define Mem(a, x) memset(a, x, sizeof(a)) 15 #define rg register 16 typedef long long ll; 17 typedef double db; 18 const int INF = 0x3f3f3f3f; 19 const db eps = 1e-8; 20 const int maxn = 1e3 + 5; 21 inline ll read() 22
{ 23 ll ans = 0; 24 char ch = getchar(), las = ; 25 while(!isdigit(ch)) las = ch, ch = getchar(); 26 while(isdigit(ch)) ans = ans * 10 + ch - 0, ch = getchar(); 27 if(las == -) ans = -ans; 28 return ans; 29 } 30 inline void write(ll x) 31 { 32 if(x < 0) putchar(-), x = -x; 33 if(x >= 10) write(x / 10); 34 putchar(x % 10 + 0); 35 } 36 37 int n, m, w; 38 char a[maxn][maxn], s[maxn]; 39 40 int len[maxn]; 41 int ch[maxn * maxn][26], val[maxn * maxn], f[maxn * maxn], cnt = 0; 42 int getnum(char c) 43 { 44 return c - A; 45 } 46 void insert(int id, char *s) 47 { 48 len[id] = strlen(s); 49 int now = 0; 50 for(int i = 0; i < len[id]; ++i) 51 { 52 int c = getnum(s[i]); 53 if(!ch[now][c]) ch[now][c] = ++cnt; 54 now = ch[now][c]; 55 } 56 val[now] = id; 57 } 58 void build() 59 { 60 queue<int> q; 61 for(int i = 0; i < 26; ++i) if(ch[0][i]) q.push(ch[0][i]); 62 while(!q.empty()) 63 { 64 int now = q.front(); q.pop(); 65 for(int i = 0; i < 26; ++i) 66 { 67 if(ch[now][i]) f[ch[now][i]] = ch[f[now]][i], q.push(ch[now][i]); 68 else ch[now][i] = ch[f[now]][i]; 69 } 70 } 71 } 72 const int dx[] = {-1, -1, 0, 1, 1, 1, 0, -1}, dy[] = {0, 1, 1, 1, 0, -1, -1, -1}; 73 struct Node 74 { 75 int x, y, d; 76 }ans[maxn]; 77 void query(int x, int y, int d) 78 { 79 int newx = x, newy = y, now = 0; 80 do 81 { 82 int c = getnum(a[newx][newy]); 83 now = ch[now][c]; 84 for(int j = now; j && val[j] != -1; j = f[j]) if(val[j] > 0) 85 { 86 ans[val[j]].x = newx - (len[val[j]] - 1) * dx[d]; 87 ans[val[j]].y = newy - (len[val[j]] - 1) * dy[d]; 88 ans[val[j]].d = d; 89 val[j] = -1; 90 } 91 newx += dx[d]; newy += dy[d]; 92 }while(newx >= 0 && newx < n && newy >= 0 && newy < m); 93 } 94 95 int main() 96 { 97 n = read(); m = read(); w = read(); 98 for(int i = 0; i < n; ++i) scanf("%s", a[i]); 99 for(int i = 1; i <= w; ++i) 100 { 101 scanf("%s", s); 102 insert(i, s); 103 } 104 build(); 105 for(int i = 0; i < n; ++i) 106 { 107 query(i, 0, 2); query(i, m - 1, 6); 108 query(i, 0, 1); query(i, m - 1, 5); 109 query(i, 0, 3); query(i, m - 1, 7); 110 } 111 for(int i = 0; i < m; ++i) 112 { 113 query(n - 1, i, 0); query(0, i, 4); 114 query(n - 1, i, 1); query(0, i, 5); 115 query(0, i, 3); query(n - 1, i, 7); 116 } 117 for(int i = 1; i <= w; ++i) printf("%d %d %c\n", ans[i].x, ans[i].y, ans[i].d + A); 118 return 0; 119 }
View Code

POJ1204 Word Puzzles