poj 1204 (AC自动机)

来源:互联网 发布:数组是一种原生类吗 编辑:程序博客网 时间:2024/05/01 05:12

将要求的串压入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 SSsecondtypedef 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);}}


原创粉丝点击