poj 1204
http://poj.org/problem?id=1204
大意:给出一个棋盘puzzle,,和w个模式串,,在棋盘中寻找模式串。。棋盘中任意一格有8个方向可以走。。
解题思路: AC自动机 + 枚举8个方向即可
get_trie(),get_ac().直接用模版。。。。
query 有一点小技巧。。需要枚举8个方向,,对于一行,我们对竖直方向上的枚举可以省略,因为我们在竖直方向上枚举时,会补充上。。
另外 我们无需枚举一行中的每一个点,,只需第一个即可,因为,,我们在一个方向上枚举时,,会包含到后面的。
#include <iostream>
#include<cstring>
using namespace std;
struct point{
point *fail;
point *next[];
bool istail;//是否为单词结尾
int id;//单词的输入顺序
point(){ //初始化
istail =false;
fail = NULL;
memset(next,NULL,sizeof(next));
}
}*q[];//bfs 获得fail 用 struct pos{
int x,y,dis;
};
pos ans[];
point *root = NULL;
int l,c,w;
char map[][];//puzzle
char str[];//模版串
int len[];//记录每个摸版的长度
int tail,head;
int dix[][] = {-,,-,,,,,,,,,-,,-,-,-};//顺时针,,上下左右。。。八个方向
char res[]={"ABCDEFGH"};
void build_trie(char *str,int id){
point *p = root;
int i=,index;
while(str[i]){
index = str[i]-'A';
if(p->next[index]==NULL) p->next[index] = new point();
p = p->next[index];
i++;
}
p->istail = true;
p->id = id;
}
void get_ac(){
int i;
root->fail = NULL;
q[head++] = root;
while(head!=tail){
point *temp = q[tail++];
point *p =NULL;
for(i=;i<;i++){
if(temp->next[i]!=NULL){
if(temp==root) temp->next[i]->fail=root;
else{
p = temp->fail;
while(p!=NULL){
if(p->next[i]!=NULL){
temp->next[i]->fail = p->next[i];
break;
}
p = p->fail;
}
if(p==NULL) temp->next[i]->fail = root;
}
q[head++] = temp->next[i];
}
}
}
} void query(int x,int y,int i){
int index;
point *p,*qq;
p = root;
for(;map[x][y];x+=dix[i][],y+=dix[i][]){
index = map[x][y]-'A';
while(p->next[index]==NULL&&p!=root) p = p->fail;
p = p->next[index];
if(p==NULL)
p = root;
qq= p;
while(qq!=root){
if(qq->istail){
qq->istail = false;
ans[qq->id].x = x-dix[i][]*(len[qq->id]-)-;//从1开始记得数
ans[qq->id].y = y-dix[i][]*(len[qq->id]-);
ans[qq->id].dis = i;
}
qq = qq->fail;
}
}
}
int main()
{
root = new point();
cin>>l>>c>>w;
for(int i=;i<=l;i++)
cin>>map[i];
for(int i=;i<w;i++){
cin>>str;
len[i] = strlen(str);
build_trie(str,i);
}
head = tail =;
get_ac();
for(int i=;i<=l;i++){//枚举水平
query(i,,),query(i,,),query(i,,);//一行只需枚举开头和结尾即可,一列同样
query(i,c-,),query(i,c-,),query(i,c-,);
}
for(int i=;i<c;i++){//枚举竖直
query(,i,),query(,i,),query(,i,);
query(l,i,),query(l,i,),query(l,i,);
} for(int i=;i<w;i++){
cout<<ans[i].x<<" "<<ans[i].y<<" "<<res[ans[i].dis]<<endl;
}
return ;
}
poj 1204的更多相关文章
- poj 1204 Word Puzzles(字典树)
题目链接:http://poj.org/problem?id=1204 思路分析:由于题目数据较弱,使用暴力搜索:对于所有查找的单词建立一棵字典树,在图中的每个坐标,往8个方向搜索查找即可: 需要注意 ...
- 【 POJ - 1204 Word Puzzles】(Trie+爆搜|AC自动机)
Word Puzzles Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 10782 Accepted: 4076 Special ...
- [POJ 1204]Word Puzzles(Trie树暴搜&AC自己主动机)
Description Word puzzles are usually simple and very entertaining for all ages. They are so entertai ...
- [poj] 1204 Word Puzzles || AC自动机
原题 给个X*Y的字符串矩阵,W个询问,对每个询问输出这个串出现的位置及方向,共有8个方向,顺时针开始分别用A~H表示 AC自动机的板子题. 对于待匹配串建一个自动机,然后从矩阵的四周分别沿八个方向跑 ...
- POJ 1204 Word Puzzles | AC 自动鸡
题目: 给一个字母矩阵和几个模式串,矩阵中的字符串可以有8个方向 输出每个模式串开头在矩阵中出现的坐标和这个串的方向 题解: 我们可以把模式串搞成AC自动机,然后枚举矩阵最外围一层的每个字母,向八个方 ...
- POJ 1204 Word Puzzles(AC自动机)
这题的数据卡在,如下: 5 5 3 ABCDE FGHIJ KLMNO PQRST UVWXY PQR RS RST puzzle中间的行中可以包含要查询的多个单词.这个问题很好解决,SearchDf ...
- POJ题目分类(按初级\中级\高级等分类,有助于大家根据个人情况学习)
本文来自:http://www.cppblog.com/snowshine09/archive/2011/08/02/152272.spx 多版本的POJ分类 流传最广的一种分类: 初期: 一.基本算 ...
- [转] POJ字符串分类
POJ 1002 - 487-3279(基础)http://acm.pku.edu.cn/JudgeOnline/problem?id=1002题意:略解法:二叉查找数,map,快排... POJ 1 ...
- ACM 字符串 题目整理
AC自动机 UVa 11468 Substring AC自动机+概率DP. 注意要补全不存在的边. 为什么要补全不存在的边呢?补全以后可以直接找到状态的转移,即从所有子节点就可以实现所有状态转移. ...
随机推荐
- Vim 实用技术,第 2 部分: 常用插件(转)
http://blog.jobbole.com/20619/ 2.1. gzip(压缩文件支持) 作者:Bram Moolenar 网站脚本编号:无(包含在 Vim 的标准发布之中) 安装说明:无 功 ...
- Codeforces 706D Vasiliy's Multiset(可持久化字典树)
[题目链接] http://codeforces.com/problemset/problem/706/D [题目大意] 要求实现一个集合中的三个操作,1:在集合中加入一个元素x,2:从集合中删除一个 ...
- hdu 2563 统计问题
统计问题 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi ...
- 展开字符串(dfs)
展开字符串 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- 模式匹配-KMP算法
/***字符串匹配算法***/ #include<cstring> #include<iostream> using namespace std; #define OK 1 # ...
- 拥抱开源,怎样关注Linux Kernel 邮件列表?
现在开源如此火爆.以至于张口闭口不提到都仿佛不是搞IT 的.那么怎样拥抱开源?本文适合刚開始学习的人,如有大神至此,goto exit ! 一.怎样增加开源 以Linux 为例,这么一个成功的开源项目 ...
- 配置vim之插件
涉及linux平台下ctags, taglist插件 ctags是一个用于产生代码索引文件的插件,它产生的索引可以帮助我们更快的定位到特定位置. ctags支持很多语言,比如java, c, c++, ...
- 2015 5.16 C# 继承和多态
类的层次结构有两种基本的构造方式 自顶向下 自底向上 基类的保护成员是指允许派生类的方法代码访问,而不是指通过派生类的对象访问 如果基类中的字段通过公有且可读写的属性进行了封装,那么建议将字段定义 ...
- iOS网络请求基础
这篇是关于网络请求的,结合公司的实际情况编写,如果有不同意见欢迎留言共同讨论. iOS在9.0之后彻底放弃了NSURLConnection,现在已经改用了NSURLSession进行网络请求.一般现在 ...
- margin 属性的相关问题
1.margin 的IE6 双边距问题 问题描述:浮动的块挨边框的时候会产生双倍的边距 解决方案: 1.增加display:inline; 2.去除float属性 2.margin 的重叠问题 CSS ...