poj 1204 (AC自动机)

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


你可能感兴趣的:(poj 1204 (AC自动机))