Word Puzzles
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 8235   Accepted: 3104   Special Judge

Description

Word puzzles are usually simple and very entertaining for all ages. They are so entertaining that Pizza-Hut company started using table covers with word puzzles printed on them, possibly with the intent to minimise their client's perception of any possible delay in bringing them their order.

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

The first line of input consists of three positive numbers, the number of lines, 0 < L <= 1000, the number of columns, 0 < C <= 1000, and the number of words to be found, 0 < W <= 1000. The following L input lines, each one of size C characters, contain the word puzzle. Then at last the W words are input one per line.

Output

Your program should output, for each word (using the same order as the words were input) a triplet defining the coordinates, line and column, where the first letter of the word appears, followed by a letter indicating the orientation of the word according to the rules define above. Each value in the triplet must be separated by one space only.

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自动机的更多相关文章

  1. POJ1204 Word Puzzles(AC自动机)

    给一个L*C字符矩阵和W个字符串,问那些字符串出现在矩阵的位置,横竖斜八个向. 就是个多模式匹配的问题,直接AC自动机搞了,枚举字符矩阵八个方向的所有字符串构成主串,然后在W个模式串构造的AC自动机上 ...

  2. 【 POJ - 1204 Word Puzzles】(Trie+爆搜|AC自动机)

    Word Puzzles Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 10782 Accepted: 4076 Special ...

  3. AC自动机练习题1:地图匹配

    AC自动机板子,学习之前要是忘记了就看一下 1465: [AC自动机]地图匹配 poj1204 时间限制: 1 Sec  内存限制: 256 MB提交: 78  解决: 46[提交] [状态] [讨论 ...

  4. 基于trie树做一个ac自动机

    基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...

  5. AC自动机-算法详解

    What's Aho-Corasick automaton? 一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一. 简单的说,KMP用来在一篇文章中匹配一个模式串:但 ...

  6. python爬虫学习(11) —— 也写个AC自动机

    0. 写在前面 本文记录了一个AC自动机的诞生! 之前看过有人用C++写过AC自动机,也有用C#写的,还有一个用nodejs写的.. C# 逆袭--自制日刷千题的AC自动机攻克HDU OJ HDU 自 ...

  7. BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2545  Solved: 1419[Submit][Sta ...

  8. BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]

    3172: [Tjoi2013]单词 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 3198  Solved: 1532[Submit][Status ...

  9. BZOJ 1212: [HNOI2004]L语言 [AC自动机 DP]

    1212: [HNOI2004]L语言 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1367  Solved: 598[Submit][Status ...

随机推荐

  1. 转:Asp JSONP 实践

    我用asp做服务端客户端 客户端页面首先在body 中放置一个div: <div id="res"></div> 将远程调用的数据写入该div中 <s ...

  2. 对WM_NCHITTEST消息的了解+代码实例进行演示(消息产生消息,共24个枚举值)

    这个消息比较实用也很关键,它代表非显示区域命中测试.这个消息优先于所有其他的显示区域和非显示区域鼠标消息.其中lParam参数含有鼠标位置的x和y屏幕坐标,wParam 这里没有用. Windows应 ...

  3. COJ 0342 逆序对(一)

    传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=312 试题描述: 给你一个大小为N的int数组A.请你统计有多少数对(Ai, ...

  4. 常用sql语句及案例(oracle)

    目录 1)基本 2)数学函数 3)rownum 4)分页 5)时间处理 6)字符函数 7)to_number 8)聚合函数 9)学生选课 10)图书馆借阅 基本 --新建表: ) ) not null ...

  5. UVAlive3713 Astronauts(2-SAT)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18511 [思路] 2-SAT. 设分得A或B类任务为1 C类任务为 ...

  6. L1签证_百度百科

    L1签证_百度百科 L1签证

  7. windows server 2003 64x 读取office数据终极解决办法 The 'Microsoft.Jet.OLEDB.4.0' provider is not registered

    微软老子信了你的邪!      试了各种办法没有效果 网友解决办法一: The 'Microsoft.Jet.OLEDB.4.0' provider is not registered on the ...

  8. 转: LRU缓存介绍与实现 (Java)

    引子: 我们平时总会有一个电话本记录所有朋友的电话,但是,如果有朋友经常联系,那些朋友的电话号码不用翻电话本我们也能记住,但是,如果长时间没有联系了,要再次联系那位朋友的时候,我们又不得不求助电话本, ...

  9. cmake编译错误:“No CMAKE_C_COMPILER could be found”的原因

    发生此错误,原因在于,进行configure命令时,没有选择正确的编译器,比如电脑上安装的是VS2012,想编译位64位,选择了VS2012 X64,这样就会报错了,选择VS2012就对了,一样可以编 ...

  10. 终于有人把O2O、C2C、B2B、B2C的区别讲透了

    一.O2O.C2C.B2B.B2C的区别在哪里? o2o 是 online to offline 分为四种运营模式 1.online to offline 是线上交易到线下消费体验 2.offline ...