【POJ1204】Word Puzzles【Trie】【暴力】

比较神奇的trie树。

当然不用对地图建8个trie,直接对单词建树即可。

枚举地图上的每个点和每个方向,深搜,在地图上边走、trie上边跑,如果找到单词结尾,那么就保存答案。


由于trie根节点并没有保存单词,所以深搜开始的节点是trie的儿子。


题目并没有告诉单词长度,一开始开了和地图一样的大小,结果MLE,最后开小了一个数量级,AC。


#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

const int maxn = 1005, maxd = 26, maxnode = 100000;

int n, m, k, sx, sy, delta[][2] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};
string g[maxn];

struct _data {
	int x, y, d;
} ans[maxn];

struct _trie {

	int son[maxnode][maxd], triecnt, id[maxnode];
	
	void init() {
		memset(son, 0, sizeof(son)); triecnt = 1; memset(id, 0, sizeof(id));
	}
	
	void insert(string s, int w) {
		int now = 1, len = s.size();
		for(int i = 0; i < len; i++) {
			int ind = s[i] - 'A';
			if(!son[now][ind]) son[now][ind] = ++triecnt;
			now = son[now][ind];
		}
		id[now] = w;
	}

	void dfs(int now, int x, int y, int d) {
		if(!now) return;
		if(id[now]) {
			ans[id[now]] = (_data) {sx, sy, d};
			id[now] = 0;
		}
		x += delta[d][0]; y += delta[d][1];
		if(x < 0 || x >= n || y < 0 || y >= m) return;
		dfs(son[now][g[x][y] - 'A'], x, y, d);
	}

} trie;

int main() {
	ios::sync_with_stdio(false);
	cin >> n >> m >> k;
	for(int i = 0; i < n; i++) cin >> g[i];
	trie.init();
	for(int i = 1; i <= k; i++) {
		string str; cin >> str;
		trie.insert(str, i);
	}

	for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) for(int d = 0; d < 8; d++) trie.dfs(trie.son[1][g[i][j] - 'A'], sx = i, sy = j, d);
	
	for(int i = 1; i <= k; i++) printf("%d %d %c\n", ans[i].x, ans[i].y, ans[i].d + 'A');
	
	return 0;
}


你可能感兴趣的:(poj,trie)