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 ...
随机推荐
- 转:Netty系列之Netty高性能之道
1. 背景 1.1. 惊人的性能数据 最近一个圈内朋友通过私信告诉我,通过使用Netty4 + Thrift压缩二进制编解码技术,他们实现了10W TPS(1K的复杂POJO对象)的跨节点远程服务调用 ...
- Node.js 安装 初体验(1)
1.安装nodejs http://nodejs.org/download/ 自动根据系统下载自己的版本node.js 2.环境变量 windows 安装,不需要配置环境变量 mac安装后,会提 ...
- Word中封面的问题
老师给了封面,当从一个文档复制到另一个文档时格式变了,即便用格式刷也解决不了一些问题,那么就把正文复制到带有封面的文档,把老师的其他内容删掉.
- poj 2886Who Gets the Most Candies?
http://poj.org/problem?id=2886 #include <cstdio> #include <cstring> #include <algorit ...
- h.264 Bi-Predictive Motion Search
在做B帧的运动预测时,有两组参考图像列表(refList0, refList1),需要进行分别前向预测.后向预测.传统的预测方式是: 对refList0进行前向预测,得到最佳前向ref与mv. 对re ...
- Quantization Method
如上一篇Quantization所说,可以在编码端通过设置offset来调整量化后的值,从而趋向于期望的量化值,而且在逆量化公式可以看出offset值在逆量化的时候是不会用到的. 目前来说,确定off ...
- HDU 1083 Courses(最大匹配模版题)
题目大意: 一共有N个学生跟P门课程,一个学生可以任意选一 门或多门课,问是否达成: 1.每个学生选的都是不同的课(即不能有两个学生选同一门课) 2.每门课都有一个代表(即P门课都被成功选过 ...
- javascript对象拷贝
浅拷贝 浅拷贝函数: function copy(p){ var c = {}; for (var i in p){ c[i] = p[i]; } c.uber = p; return c; } 测试 ...
- C++編程札記「基礎」
一直以為自己最擅長的編程語言是C++,那時自己的水平停留在使用C++來實現數據結構中的各種ADT和ACM算法. 創建一個類,必須實現的成員函數 explicit構造函數 對於單參數構造函數,添加exp ...
- 网络智能和大数据公开课Homework3 Map-Reduce编程
Web Intelligence and Big Data by Dr. Gautam Shroff 这门课是关于大数据处理,本周是第一次编程作业,要求使用Map-Reduce对文本数据进行统计.使用 ...