您的位置:首页 > 其它

poj 1204 (AC自动机)

2013-08-13 22:05 309 查看
将要求的串压入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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: