Poj 1204 简单AC自动机
2011-08-22 08:57
337 查看
题目链接:http://poj.org/problem?id=1204
题意:给出一个字符方阵和一系列字符串,试从方阵中找出字符串出现的位置,方阵中字符串按八个方向查询。
将待查询字符串插入字典树,构造AC自动机,然后对方阵的四条边,每条边对应的三个方向进行查询。
Code:
题意:给出一个字符方阵和一系列字符串,试从方阵中找出字符串出现的位置,方阵中字符串按八个方向查询。
将待查询字符串插入字典树,构造AC自动机,然后对方阵的四条边,每条边对应的三个方向进行查询。
Code:
#include<stdio.h> #include<stdlib.h> #include<string.h> #define M 1024 typedef struct{ int x,y,d; }Result; typedef struct talT{ int k; talT *fail,*nxt[26]; }Trie; int dir[][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}}; Result res[M]; char s[M][M]; char tmp[M]; int size; Trie Memory[M<<8]; Trie *q[M<<8]; Trie *r; int len[M]; int head,tail; int l,c,w; Trie *NewTrie() { return &Memory[size++]; } int Legal(int x,int y) { if(x<0||x>=l) return 0; if(y<0||y>=c) return 0; return 1; } void Insert(char *p,int k) { Trie *cur=r; int a; while(*p){ a=*p++-'A'; if(!cur->nxt[a]) cur->nxt[a]=NewTrie(); cur=cur->nxt[a]; } cur->k=k; } void ACAutomation() { Trie *cur,*pre; int i; head=tail=0; r->fail=NULL; q[tail++]=r; while(head^tail){ cur=q[head++]; for(i=0;i<26;i++){ if(!cur->nxt[i]) continue; if(cur==r) cur->nxt[i]->fail=r; else{ pre=cur->fail; while(pre&&!pre->nxt[i]) pre=pre->fail; cur->nxt[i]->fail=pre?pre->nxt[i]:r; } q[tail++]=cur->nxt[i]; } } } void ACRun(int x,int y,int d) { int a; Trie *tmp,*cur=r; for(;Legal(x,y);x+=dir[d][0],y+=dir[d][1]){ a=s[x][y]-'A'; while(!cur->nxt[a]&&cur!=r) cur=cur->fail; cur=cur->nxt[a]; if(cur==NULL) cur=r; tmp=cur; while(tmp!=r&&tmp->k){ res[tmp->k].x=x-dir[d][0]*(len[tmp->k]-1); res[tmp->k].y=y-dir[d][1]*(len[tmp->k]-1); res[tmp->k].d=d; tmp->k=0; tmp=tmp->fail; } } } void ACWork() { int i; for(i=0;i<c;i++){ ACRun(0,i,3);ACRun(0,i,4);ACRun(0,i,5); ACRun(c-1,i,0);ACRun(c-1,i,1);ACRun(c-1,i,7); } for(i=0;i<l;i++){ ACRun(i,0,1);ACRun(i,0,2);ACRun(i,0,3); ACRun(i,c-1,5);ACRun(i,c-1,6);ACRun(i,c-1,7); } } int main() { int i; scanf("%d%d%d",&l,&c,&w); for(i=0;i<l;i++) scanf("%s",s[i]); r=NewTrie(); for(i=1;i<=w;i++){ scanf("%s",tmp); len[i]=strlen(tmp); Insert(tmp,i); } ACAutomation(); ACWork(); for(i=1;i<=w;i++) printf("%d %d %c\n",res[i].x,res[i].y,res[i].d+'A'); return 0; }
相关文章推荐
- POJ 1204 AC自动机的初步认识+模板题
- POJ1204 Word Puzzles(AC自动机)
- poj - 1204 - Word Puzzles(AC自动机)
- poj 1204 AC自动机
- poj 1204 Word Puzzles (ac自动机)
- Censored! - POJ 1625(ac自动机+简单dp+高精度运算)
- poj 1204 (AC自动机)
- POJ 1204 Word Puzzles(AC自动机)
- poj1204之AC自动机
- poj 1204:Word Puzzles(AC自动机)
- poj 1204 Word Puzzles (AC自动机)
- POJ 1204(AC自动机)
- [poj] 1204 Word Puzzles || AC自动机
- POJ 1204 AC自动机
- POJ 1204 Word Puzzles (AC自动机)
- 一个自己编写的简单AC自动机代码-----AC automata get √
- Poj 3691 & Hdu 2457 DNA repair (AC自动机+DP)
- poj 2778 (AC自动机+dp+矩阵快速幂)
- poj 3691 DNA repair(AC自动机+DP)
- HDU3065(病毒侵袭持续中)字符串匹配-简单的AC自动机