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 ...
随机推荐
- Install RHadoop with Hadoop 2.2 – Red Hat Linux
Prerequisite Hadoop 2.2 has been installed (and the below installation steps should be applied on ea ...
- poj 3686 The Windy's
http://poj.org/problem?id=3686 #include <cstdio> #include <cstring> #include <algorit ...
- BROCADE 300和MD3200扩展柜FC SAN,截图
这表示俺玩过,其实,这个光交换机在只有一个共享存储的情况下,可用可不用. FC BROCADE只是为了方便后期扩展. FC SAN之类的识别不靠IP,因为不是IP SAN嘛.但也是自己的识别体系.
- Symmetric Tree——LeetCode
Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). For e ...
- 慕课网《Android智能机器人“小慕”的实现》项目上手操作与代码解读【2】
前几天有点忙,一直没写第三方API是怎么调用的,今天我先介绍一下如何调用图灵机器人第三方API. 一.图灵机器人API的调用 首先登录图灵机器人官网首页http://www.tuling123.com ...
- [Linux] 流 ( Stream )、管道 ( Pipeline ) 、Filter - 笔记
流 ( Stream ) 1. 流,是指可使用的数据元素一个序列. 2. 流,可以想象为是传送带上等待加工处理的物品,也可以想象为工厂流水线上的物品. 3. 流,可以是无限的数据. 4. 有一种功能, ...
- D - Constructing Roads - 2421
题意:有一些村庄需要修一些道路是所有村庄都可以连接,不过有些道路已经修好了,问题最少还需要修建的道路长度是多少. 输入的第一行是一个N代表N个村庄,下面是一个N*N的矩阵,代表着q->j的距离, ...
- flash 中无法导出swf文件的解决方法
近一个星期,我的flash cs6一直导不出swf文件,郁闷了好长时间,今天终于在网上找到了解决办法:总结了一下,如下: 一.是把文字打散,变成形状. 二.是把汉字的字体设成fla ...
- 在DataTable和DataView中查找指定记录
一.在DataTable中查找 1. 使用Select方法查找没有主键的表DataTable的Select方法返回一个DataRow数组,有四个重载的函数. DataRow[] drs = dt.Se ...
- ubuntu14.04 安装
summary: a). the way in the internet just a sugestion, I must to do it in my own hands, yes ! just ...