POJ 1204 Word Puzzles // 字典树,枚举, 搜索
2015-10-26 23:26
411 查看
题目描述
POJ 1204 Word Puzzles解题思路
题目大意:给出一个Word Puzzles,然后询问每个单词在其中出现的坐标(i, j, dir)
i 为单词首字母的横坐标 ,j为纵坐标,dir为八方向之一(用A~H表示)
这题我一开始是将Word Puzzles所有可能的单词建Trie,然后每个单词维护(i,j,dir)的信息,这样的话时间和空间的消耗都特别巨大,因此应该换一个思路。由于查询的单词最多就1K个,因此以查询的单词来建Trie是比较合适的,然后再在Word Puzzles中枚举即可。
参考代码
//********************************************** // Author: @xmzyt1996 // Date: 2015-10-21 // Name: POJ 1204.cpp //********************************************** #include <cstdio> #include <cmath> #include <cctype> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <string> #include <bitset> #include <vector> #include <stack> #include <queue> #include <map> using namespace std; #define clr(a, b) memset(a, b, sizeof(a)) #define rep(i, a, b) for(int i = a; i < b; ++i) #define per(i, a, b) for(int i = a; i >= b; --i) #define print(x) cout << #x << " = " << x << endl #define ps puts("debug~~") #define all(x) (x).begin(),(x).end() #define mp make_pair #define pb push_back typedef __int64 ll; typedef pair<int, int> pii; const double pi = acos(-1.0); const double eps = 1e-6; const int inf = 0x3f3f3f3f; const int MOD = 1e9+7; const int MAX_N = 1010; struct Trie { Trie* next[26]; int idx; bool flag; }node[MAX_N*100]; int num, rr[MAX_N], cc[MAX_N], cnt, r, c, w; char ff[MAX_N], word[MAX_N][MAX_N], s[MAX_N]; int dir[8][2] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}}; // 八方向 void init () { num = 0; memset(node, 0, sizeof(node)); } int getid (char c) { return c - 'A'; } bool check (int i, int j) { return (i >= 0 && i < r && j >= 0 && j < c); } // 检查下标是否越界 void insert (char* s, int idx) { //将待查询单词s插入Trie中,编号为idx Trie* head = &node[0]; while (*s) { int id = getid(*s++); if ((head->next[id]) == NULL) head->next[id] = &node[++num]; head = head->next[id]; } head->flag = 1; head->idx = idx; } void search (int i, int j, int k) { // 以Word Puzzles[i][j]为起点,方向为k(0~7) 开始搜索 Trie* head = &node[0]; int x = i, y = j; while (check(x, y)) { int id = getid(word[x][y]); head = head->next[id]; if (head == NULL) return ; if (head->flag) { int idx = head->idx; rr[idx] = i, cc[idx] = j; ff[idx] = k + 'A'; cnt++; head->flag = 0; // 找到之后记得去掉标记,防止重复查找 } x += dir[k][0], y += dir[k][1]; } } void work () { rep(i, 0, r) rep(j, 0, c) rep(k, 0, 8) { // 枚举Word Puzzles search(i, j, k); if (cnt == w) return ; // w个单词全部找到,可以return了 } } int main() { scanf("%d %d %d", &r, &c, &w); rep(i, 0, r) scanf("%s", word[i]); init(); rep(i, 0, w) { scanf("%s", s); insert(s, i); } work(); rep(i, 0, w) printf("%d %d %c\n", rr[i], cc[i], ff[i]); return 0; }
相关文章推荐
- Leetcode_257_Binary Tree Paths
- Java面试题全集(上)
- Leetcode_257_Binary Tree Paths
- 子序列
- tp框架搭建
- 浏览器中JavaScript执行原理
- Android利用Fiddler进行网络数据抓包
- 怎么查询NSLog中每个数据类型对应的占位符
- Windows 下实现线程局部存储
- 网站外部链接(读书笔记)
- 自定义泛型类型和方法
- 利用BOOST,解释JSON
- 【2015/10/25】C 学习日志_Day10 运算符
- UML学习笔记之状态图
- Bank,我只是来完成作业的
- 为何在新建的client中无法用sap*登录?
- Daily Srum 10.26
- 《Intel汇编第5版》 汇编减法程序
- 乘法口诀
- 属性之get,set