POJ 1204 Word Puzzles // 字典树,枚举, 搜索

来源:互联网 发布:淘宝网买家地域解读 编辑:程序博客网 时间:2024/05/29 10:26

题目描述

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_backtypedef __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;}
0 0
原创粉丝点击