题目描述
解题思路
题目大意:
给出一个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;
}