poj1204之AC自动机
| Time Limit: 5000MS | Memory Limit: 65536K | |||
| Total Submissions: 8235 | Accepted: 3104 | Special Judge | ||
Description
Even though word puzzles may be entertaining to solve by hand, they may become boring when they get very large. Computers do not yet get bored in solving tasks, therefore we thought you could devise a program to speedup (hopefully!) solution finding in such puzzles.
The following figure illustrates the PizzaHut puzzle. The names of the pizzas to be found in the puzzle are: MARGARITA, ALEMA, BARBECUE, TROPICAL, SUPREMA, LOUISIANA, CHEESEHAM, EUROPA, HAVAIANA, CAMPONESA.

Your task is to produce a program that given the word puzzle and words to be found in the puzzle, determines, for each word, the position of the first letter and its orientation in the puzzle.
You can assume that the left upper corner of the puzzle is the origin, (0,0). Furthemore, the orientation of the word is marked clockwise starting with letter A for north (note: there are 8 possible directions in total).
Input
Output
Sample Input
20 20 10
QWSPILAATIRAGRAMYKEI
AGTRCLQAXLPOIJLFVBUQ
TQTKAZXVMRWALEMAPKCW
LIEACNKAZXKPOTPIZCEO
FGKLSTCBTROPICALBLBC
JEWHJEEWSMLPOEKORORA
LUPQWRNJOAAGJKMUSJAE
KRQEIOLOAOQPRTVILCBZ
QOPUCAJSPPOUTMTSLPSF
LPOUYTRFGMMLKIUISXSW
WAHCPOIYTGAKLMNAHBVA
EIAKHPLBGSMCLOGNGJML
LDTIKENVCSWQAZUAOEAL
HOPLPGEJKMNUTIIORMNC
LOIUFTGSQACAXMOPBEIO
QOASDHOPEPNBUYUYOBXB
IONIAELOJHSWASMOUTRK
HPOIYTJPLNAQWDRIBITG
LPOINUYMRTEMPTMLMNBO
PAFCOPLHAVAIANALBPFS
MARGARITA
ALEMA
BARBECUE
TROPICAL
SUPREMA
LOUISIANA
CHEESEHAM
EUROPA
HAVAIANA
CAMPONESA
Sample Output
0 15 G
2 11 C
7 18 A
4 8 C
16 13 B
4 15 E
10 3 D
5 1 E
19 7 C
11 11 H
题意:输入n,m,w代表先给定n行m列字符,接下来w行每行给定一组字符串,求该字符串在n*m的矩阵中首先出现的起始位置,字符串可以和矩阵中以某点开始8个方向进行匹配
输出首先匹配的起始点坐标和匹配的方向
方向为A,B,C,D...
分析:将w各字符串插入字典树,然后用n*m的矩阵去匹配,匹配方法是枚举8个方向去匹配
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<map>
#include<iomanip>
#define INF 99999999
using namespace std; const int MAX=1000+10;
char s[MAX][MAX],b[MAX];
int n,m,w;
int dir[8][2]={0,1,0,-1,1,0,-1,0,1,1,-1,-1,1,-1,-1,1};//八个方向
char ch[9]="CGEADHFB";
int pos[MAX][3]; struct TrieNode{
int id;//记录第几个字符串
TrieNode *next[26],*fail;
TrieNode(){
id=0;
fail=0;
memset(next,0,sizeof next);
}
}*root; void InsertNode(char *a,int id){
int len=strlen(a)-1;
TrieNode *p=root;
while(len>=0){//这里将a数组倒着插入字典树,方便匹配时记录匹配的终点即原串的起始点
if(!p->next[a[len]-'A'])p->next[a[len]-'A']=new TrieNode;
p=p->next[a[len--]-'A'];
}
p->id=id;
} void Build_AC(){
TrieNode *p=root,*next;
queue<TrieNode *>q;
q.push(root);
while(!q.empty()){
p=q.front();
q.pop();
for(int i=0;i<26;++i){
if(p->next[i]){
next=p->fail;
while(next && !next->next[i])next=next->fail;
if(next)p->next[i]->fail=next->next[i];
else p->next[i]->fail=root;
q.push(p->next[i]);
}
}
}
} void SearchTrie(int x,int y,int d,int id){
TrieNode *p=root,*next;
while(x>=0 && y>=0 && x<n && y<m){
while(p && !p->next[s[x][y]-'A'])p=p->fail;
if(!p)p=root;
else p=p->next[s[x][y]-'A'];
next=p;
while(next != root){
if(next->id){//记录原串被匹配的起始点
int k=next->id;
if(pos[k][0]>x || (pos[k][0] == x && pos[k][1]>y)){
pos[k][0]=x,pos[k][1]=y,pos[k][2]=id;
}
}
next=next->fail;
}
x+=dir[d][0];
y+=dir[d][1];
}
} void Free(TrieNode *p){
for(int i=0;i<26;++i)if(p->next[i])Free(p->next[i]);
delete p;
} int main(){
while(cin>>n>>m>>w){
root=new TrieNode;
for(int i=0;i<n;++i)cin>>s[i];
for(int i=1;i<=w;++i){
cin>>b;
InsertNode(b,i);
pos[i][0]=pos[i][1]=INF;
}
Build_AC();
for(int i=0;i<n;++i){
SearchTrie(i,0,0,1),SearchTrie(i,m-1,1,0);//匹配左右方向
SearchTrie(i,0,7,6),SearchTrie(i,m-1,6,7);//匹配左上部分的右上角和右下部分左下角
SearchTrie(i,0,4,5),SearchTrie(i,m-1,5,4);//匹配左下部分右下角和右上部分左上角
}
for(int i=0;i<m;++i){
SearchTrie(0,i,2,3),SearchTrie(n-1,i,3,2);//匹配上下方向
SearchTrie(0,i,6,7),SearchTrie(n-1,i,7,6);//匹配左上部分左下角和右下部分右上角
SearchTrie(0,i,4,5),SearchTrie(n-1,i,5,4);//匹配右上部分的右下角和左下部分左上角
}
for(int i=1;i<=w;++i)cout<<pos[i][0]<<' '<<pos[i][1]<<' '<<ch[pos[i][2]]<<endl;
Free(root);
}
return 0;
}
poj1204之AC自动机的更多相关文章
- POJ1204 Word Puzzles(AC自动机)
给一个L*C字符矩阵和W个字符串,问那些字符串出现在矩阵的位置,横竖斜八个向. 就是个多模式匹配的问题,直接AC自动机搞了,枚举字符矩阵八个方向的所有字符串构成主串,然后在W个模式串构造的AC自动机上 ...
- 【 POJ - 1204 Word Puzzles】(Trie+爆搜|AC自动机)
Word Puzzles Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 10782 Accepted: 4076 Special ...
- AC自动机练习题1:地图匹配
AC自动机板子,学习之前要是忘记了就看一下 1465: [AC自动机]地图匹配 poj1204 时间限制: 1 Sec 内存限制: 256 MB提交: 78 解决: 46[提交] [状态] [讨论 ...
- 基于trie树做一个ac自动机
基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...
- AC自动机-算法详解
What's Aho-Corasick automaton? 一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一. 简单的说,KMP用来在一篇文章中匹配一个模式串:但 ...
- python爬虫学习(11) —— 也写个AC自动机
0. 写在前面 本文记录了一个AC自动机的诞生! 之前看过有人用C++写过AC自动机,也有用C#写的,还有一个用nodejs写的.. C# 逆袭--自制日刷千题的AC自动机攻克HDU OJ HDU 自 ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
- BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3198 Solved: 1532[Submit][Status ...
- BZOJ 1212: [HNOI2004]L语言 [AC自动机 DP]
1212: [HNOI2004]L语言 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1367 Solved: 598[Submit][Status ...
随机推荐
- 【转】HashMap和HashSet的区别
原文网址:http://www.importnew.com/6931.html HashMap和HashSet的区别是Java面试中最常被问到的问题.如果没有涉及到Collection框架以及多线程的 ...
- CSU 1160 把十进制整数转换为十六进制,格式为0x开头,10~15由大写字母A~F表示
题目链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82974#problem/A 解题思路: 将16进制的表示方法列在一个数组里面 ...
- 弱爆了的Candies
题目出处 题目描述: n个小朋友坐成一排,每个小朋友有一个数表示他的表现(数字越大表现越好).老师要给每个小朋友发至少1颗糖,相邻的两个小朋友,得分较高的小朋友必须得到更多的糖,问:老师至少需要给出多 ...
- C# 我是个传奇的 using
呵呵呵: ----------------------------------------------------------------------------------------------- ...
- HTTP meta 设置方法
网页的缓存是由 HTTP 消息头中的 “Cache-control” 来控制的,常见的取值有 private.no-cache.max-age.must-revalidate 等,默认为private ...
- 那些年,学swift踩过的坑
最近在学swift,本以为多是语法与oc不同,而且都是使用相同的cocoa框架,相同的API,但是或多或少还是有些坑在里,为了避免以后再踩,在这里记下了,以后发现新的坑,也会慢慢在这里加上 [TOC] ...
- 用Hexo搭建属于自己的Blog
什么是Hexo 简单的来说,Hexo是一款基于Node.JS的静态博客框架,官方给它的描述是"A fast, simple & powerful blog framework&quo ...
- Python 常量与变量
先在lib文件夹中定义一个模块 class _const(object): class ConstError(TypeError):pass def __setattr__(self, name, v ...
- 开发部署一个简单的Servlet
Servlet是一个执行在服务器端的Java Class文件,载入前必须先将Servlet程序代码编译成.class文件,然后将此class文件放在servlet Engline路径下.Servlet ...
- Java 小型学生管理系统心得
这个学生管理系统相对来说比较简单,主要就是复习下java怎么连接数据库,然后你怎么来实现这个功能,我简单的说下思路吧. 首先你要构思好这个界面,他包括增删查改这些基本功能,然后你去分析这些功能都能怎么 ...