将要求的串压入trie树,枚举矩阵横,竖,斜查询
#include <set> #include <map> #include <list> #include <queue> #include <stack> #include <cmath> #include <string> #include <cstdio> #include <vector> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define PB push_back #define SIZE(x) (int)x.size() #define clr(x,y) memset(x,y,sizeof(x)) #define MP(x,y) make_pair(x,y) #define reads(n) scanf ("%s", n) #define ALL(t) (t).begin(),(t).end() #define FOR(i,n,m) for (int i = n; i <= m; i ++) #define ROF(i,n,m) for (int i = n; i >= m; i --) #define IT iterator #define FF first #define SS second typedef long long ll; typedef unsigned int uint; typedef unsigned long long ull; typedef vector<int> vint; typedef vector<string> vstring; typedef pair<int, int> PII; void RI (int& x){ x = 0; char c = getchar (); while (c == ' '||c == '\n') c = getchar (); bool flag = 1; if (c == '-'){ flag = 0; c = getchar (); } while (c >= '0' && c <= '9'){ x = x * 10 + c - '0'; c = getchar (); } if (!flag) x = -x; } void RII (int& x, int& y){RI (x), RI (y);} void RIII (int& x, int& y, int& z){RI (x), RI (y), RI (z);} /**************************************END define***************************************/ const ll mod = 1e9+7; const ll LINF = 1e18; const int INF = 1e9; const double EPS = 1e-8; const int NODE = 500005; const int CHD = 26; char g[1005][1005]; int r, c; struct ANS{ int x, y; char c; }ans[1005]; struct ACAutomaton{ private: int chd[NODE][CHD]; PII val[NODE]; int fail[NODE]; int sz; public: void init (){ clr (chd[0], 0); sz = 1; } void insert (char* s, int key){ int p = 0; int len = strlen (s); FOR (i, 0, len-1){ int c = s[i] - 'A'; if (!chd[p][c]){ clr (chd[sz], 0); val[sz] = MP (0, 0); chd[p][c] = sz ++; } p = chd[p][c]; } val[p].FF = key; val[p].SS = len-1; } void getfail (){ queue<int> q; FOR (i, 0, CHD-1){ if (chd[0][i]){ fail[chd[0][i]] = 0; q.push (chd[0][i]); } } while (SIZE (q)){ int u = q.front (); q.pop (); FOR (i, 0, CHD - 1){ int v = chd[u][i]; if (v){ q.push (v); int tmp = fail[u]; while (tmp&&!chd[tmp][i]){ tmp = fail[tmp]; } tmp = chd[tmp][i]; fail[v] = tmp; } } } } bool check (int x, int y){ if (x < 0||y < 0) return false; if (x >= r||y >= c) return false; return true; } void find (int sx, int sy, char dir, int dx, int dy){ int p = 0; while (check (sx, sy)){ int c = g[sx][sy] - 'A'; while (p && !chd[p][c]){ p = fail[p]; } if (chd[p][c]){ p = chd[p][c]; int tmp = p; while (tmp){ if (val[tmp].first != 0){ int len = val[tmp].SS; int tx = sx - len*dx; int ty = sy - len*dy; int num = val[tmp].FF; ans[num].x = tx; ans[num].y = ty; ans[num].c = dir; } tmp = fail[tmp]; } } sx += dx, sy += dy; } } }ac; char s[1000]; int main (){ //freopen ("in", "r", stdin); int n; ac.init (); RIII (r, c, n); FOR (i, 0, r-1){ gets (g[i]); } FOR (i, 1, n){ gets (s); ac.insert (s, i); } ac.getfail (); FOR (i, 0, r-1) ac.find (i, 0, 'C', 0, 1); FOR (i, 0, c-1) ac.find (0, i, 'E', 1, 0); FOR (i, 0, r-1) ac.find (i, c-1, 'G', 0, -1); FOR (i, 0, c-1) ac.find (r-1, i, 'A', -1, 0); FOR (i, 0, r-1) ac.find (i, 0, 'D', 1, 1); FOR (i, 1, c-1) ac.find (0, i, 'D', 1, 1); FOR (i, 0, r-1) ac.find (i, 0, 'B', -1, 1); FOR (i, 1, c-1) ac.find (r-1, i, 'B', -1, 1); FOR (i, 0, c-1) ac.find (0, i, 'F', 1, -1); FOR (i, 1, r-1) ac.find (i, c-1, 'F', 1, -1); FOR (i, 0, c-1) ac.find (r-1, i, 'H', -1, -1); FOR (i, 1, r-1) ac.find (i, c-1, 'H', -1, -1); FOR (i, 1, n){ printf ("%d %d %c\n", ans[i].x, ans[i].y, ans[i].c); } }