1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <algorithm> #include <cmath> #include <cctype> #include <iostream> #include <bitset> #include <queue> #include <climits> const int INF = INT_MAX >> 1; const int MAXN = 1000 + 10; char s[MAXN][MAXN], b[MAXN]; int n, m, w; int dir[8][2] = {0, 1, 0, -1, 1, 0, -1, 0, 1, 1, -1, -1, 1, -1, -1, 1}; char ch[9] = "CGEADHFB"; int pos[MAXN][3]; struct Node { int id; Node *next[26], *fail; Node() { id = 0, fail = 0, memset(next, 0, sizeof(next)); } } *root; inline void insert(const char *s, int id) { register int len = strlen(s) - 1; Node *p = root; while (len >= 0) { if (!p->next[s[len] - 'A']) p->next[s[len] - 'A'] = new Node; p = p->next[s[len--] - 'A']; } p->id = id; } inline void build() { Node *p = root, *next; std::queue<Node *>q; q.push(root); while (!q.empty()) { p = q.front(), q.pop(); for (register int i = 0; i < 26; ++i) { if (p->next[i]) { next = p->fail; while (next && !next->next[i]) next = next->fail; p->next[i]->fail = (next ? next->next[i] : root), q.push(p->next[i]); } } } } inline void query(int x, int y, int d, int id) { Node *p = root, *next; while (x >= 0 && y >= 0 && x < n && y < m) { while (p && !p->next[s[x][y] - 'A']) p = p->fail; next = p = (p ? p->next[s[x][y] - 'A'] : root); while (next != root) { if (next->id) { register int k = next->id; if (pos[k][0] > x || (pos[k][0] == x && pos[k][1] > y)) pos[k][0] = x, pos[k][1] = y, pos[k][2] = id; } next = next->fail; } x += dir[d][0], y += dir[d][1]; } } inline void clear(Node *p) { for (register int i = 0; i < 26; ++i) if (p->next[i]) clear(p->next[i]); delete p; }
int main() { std::ios::sync_with_stdio(0), std::cin.tie(0); while (std::cin >> n >> m >> w) { root = new Node; for (register int i = 0; i < n; ++i) std::cin >> s[i]; for (register int i = 1; i <= w; ++i) std::cin >> b, insert(b, i), pos[i][0] = pos[i][1] = INF; build(); for (register int i = 0; i < n; ++i) { query(i, 0, 0, 1), query(i, m - 1, 1, 0); query(i, 0, 7, 6), query(i, m - 1, 6, 7); query(i, 0, 4, 5), query(i, m - 1, 5, 4); } for (register int i = 0; i < m; ++i) { query(0, i, 2, 3), query(n - 1, i, 3, 2); query(0, i, 6, 7), query(n - 1, i, 7, 6); query(0, i, 4, 5), query(n - 1, i, 5, 4); } for (register int i = 1; i <= w; ++i) std::cout << pos[i][0] << ' ' << pos[i][1] << ' ' << ch[pos[i][2]] << "\n"; clear(root); } return 0; }
|