题目:

给一个字母矩阵和几个模式串,矩阵中的字符串可以有8个方向

输出每个模式串开头在矩阵中出现的坐标和这个串的方向


题解:

我们可以把模式串搞成AC自动机,然后枚举矩阵最外围一层的每个字母,向八个方向进行匹配

代码中danger标记为判断这个节点是不是一个模式串的结尾,

这道题可以直接字符串反向构建AC自动机,匹配到的就是开头(代码是正向)

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define Z 27
#define N 1010
using namespace std;
struct node
{
int trans[Z],fail,danger;
void init()
{
memset(trans,0,sizeof(trans));
danger=fail=0;
}
}tr[1000010];
char puzzle[N][N],s[N],dir[10]={'A','B','C','D','E','F','G','H'};
int l,c,w,dx[10]={-1,-1,0,1,1,1,0,-1},dy[10]={0,1,1,1,0,-1,-1,-1};
int fa[N],ansx[N],ansy[N],tot=1,len[N],d[N]; int find(int x)
{
return fa[x]=fa[x]==x?x:find(fa[x]);
} void insert(char s[],int id)
{
int len=strlen(s+1),now=1;
for (int i=1;i<=len;i++)
{
if (tr[now].trans[s[i]-'A']==0)
tr[tr[now].trans[s[i]-'A']=++tot].init();
now=tr[now].trans[s[i]-'A'];
}
if (tr[now].danger)
fa[find(id)]=find(tr[now].danger);
else
tr[now].danger=id;
} void BuildFail()
{
queue <int> q;
tr[1].fail=1;
for (int i=0;i<26;i++)
{
if (tr[1].trans[i]==0)
tr[1].trans[i]=1;
else
{
tr[tr[1].trans[i]].fail=1;
q.push(tr[1].trans[i]);
}
}
while (!q.empty())
{
int u=q.front(),v,w;
for (int i=0;i<26;i++)
{
v=tr[u].fail;
v=tr[v].trans[i],w=tr[u].trans[i];
if (w) tr[w].fail=v,q.push(w);
else tr[u].trans[i]=v;
}
q.pop();
if (tr[u].danger==0 && tr[tr[u].fail].danger)
tr[u].danger=tr[tr[u].fail].danger;
}
} void query(int x,int y,int t)
{
int p=1;
while (x>0 && y>0 && x<=l && y<=c)
{
p=tr[p].trans[puzzle[x][y]-'A'];
int ap=p;
while (tr[ap].danger)
{
int k=tr[ap].danger;
ansx[k]=x-dx[t]*(len[k]-1);
ansy[k]=y-dy[t]*(len[k]-1);
d[k]=t;
ap=tr[ap].fail;
}
x+=dx[t];
y+=dy[t];
}
} int main()
{
scanf("%d%d%d",&l,&c,&w);
for (int i=1;i<=l;i++)
scanf("%s",puzzle[i]+1);
for (int i=1;i<=w;i++)
{
scanf("%s",s+1);
fa[i]=i;
len[i]=strlen(s+1);
insert(s,i);
}
BuildFail();
for (int i=1;i<=l;i++)
for (int j=0;j<8;j++)
query(i,1,j),query(i,c,j);
for (int i=1;i<=c;i++)
for (int j=0;j<8;j++)
query(1,i,j),query(l,i,j);
for (int i=1;i<=w;i++)
printf("%d %d %c\n",ansx[i]-1,ansy[i]-1,dir[d[i]]);
return 0;
}

POJ 1204 Word Puzzles | AC 自动鸡的更多相关文章

  1. [poj] 1204 Word Puzzles || AC自动机

    原题 给个X*Y的字符串矩阵,W个询问,对每个询问输出这个串出现的位置及方向,共有8个方向,顺时针开始分别用A~H表示 AC自动机的板子题. 对于待匹配串建一个自动机,然后从矩阵的四周分别沿八个方向跑 ...

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

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

  3. [POJ 1204]Word Puzzles(Trie树暴搜&amp;AC自己主动机)

    Description Word puzzles are usually simple and very entertaining for all ages. They are so entertai ...

  4. POJ 1204 Word Puzzles(AC自动机)

    这题的数据卡在,如下: 5 5 3 ABCDE FGHIJ KLMNO PQRST UVWXY PQR RS RST puzzle中间的行中可以包含要查询的多个单词.这个问题很好解决,SearchDf ...

  5. poj 1204 Word Puzzles(字典树)

    题目链接:http://poj.org/problem?id=1204 思路分析:由于题目数据较弱,使用暴力搜索:对于所有查找的单词建立一棵字典树,在图中的每个坐标,往8个方向搜索查找即可: 需要注意 ...

  6. PKU 1204 Word Puzzles(AC自动机)

    题目大意:原题链接 给定一个字符串矩阵和待查找的单词,可以朝8个不同的方向查找,输出待查找单词第一个字母在矩阵中出现的位置和该单词被查到的方向. A~H代表8个不同的方向,A代表正北方向,其他依次以4 ...

  7. POJ 题目1204 Word Puzzles(AC自己主动机,多个方向查询)

    Word Puzzles Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 10244   Accepted: 3864   S ...

  8. pku1204 Word Puzzles AC自动机 二维字符串矩阵8个方向找模式串的起点坐标以及方向 挺好的!

    /** 题目:pku1204 Word Puzzles 链接:http://poj.org/problem?id=1204 题意:给定一个L C(C <= 1000, L <= 1000) ...

  9. POJ 2778 DNA Sequence (矩阵快速幂 + AC自动鸡)

    题目:传送门 题意: 给你m个病毒串,只由(A.G.T.C) 组成, 问你生成一个长度为 n 的 只由 A.C.T.G 构成的,不包含病毒串的序列的方案数. 解: 对 m 个病毒串,建 AC 自动机, ...

随机推荐

  1. github上更新fork项目

    转载:https://blog.csdn.net/qq1332479771/article/details/56087333 ps:需要用GitHub所指定的chrome或者firefox浏览器,其它 ...

  2. LINUX安装好后无法访问网络

    LINUX安装好后无法访问网络 在虚拟机安装好新的LINUX系统后,ping www.baidu.com ,发现无法ping通. 键入ifconfig查询配置: eno16777728: flags= ...

  3. 深入理解java虚拟机学习笔记(二)垃圾回收策略

    上篇文章介绍了JVM内存模型的相关知识,其实还有些内容可以更深入的介绍下,比如运行时常量池的动态插入,直接内存等,后期抽空再完善下上篇博客,今天来介绍下JVM中的一些垃圾回收策略.        一. ...

  4. vim编辑器使用习惯问题

    Ubuntu中vi在编辑状态下方向键不能用,一按方向键盘就出ABCD,想插入个字母还非常麻烦,还有回格键不能删除等我们平时习惯的一些键都不能使用. 解决办法: 可以安装vim full版本,在full ...

  5. MySQL基础 (麦子学员 php 第二阶段)

    通过my.ini配置文件修改字符集:客户端字符集设置:[mysql]default-character-set=utf8 [mysqld] character-set-server=utf8 .设置之 ...

  6. Linux系统完整安装在虚拟机Mini

    打开VMware Workstation虚拟机,然后如下图一步到位: 此处只是简单的安装Linux系统,要想查看安装后的IP等配置看: https://www.cnblogs.com/gentle-a ...

  7. Linux两种方式rd.break和init重置root管理员密码

    centos7/rhel7进入单用户方式和重置密码方式发生了较大变化,GRUB由b引导变成了ctrl+x引导. 重置密码主要有rd.break和init两种方法. rd.break方法: 1.启动的时 ...

  8. Codeforces Round #481 (Div. 3) 全题解

    A题,题目链接:http://codeforces.com/contest/978/problem/A 解题心得:题意就是让你将这个数列去重,重复的数只保留最右边的那个,最后按顺序打印数列.set+m ...

  9. 笔记-python-lib-lxml

    笔记-python-lib-lxml 1.      lxml简介 lxml是一个实现解析网页文件的库,python中自带有解析库,但没有lxml方便好用. The lxml XML toolkit ...

  10. 减少Android staido 占用C 盘

    1.gradle 更换文件夹: 设置GRADLE_USER_HOME环境变量 在/etc/profile或~/.bash_profile增加如下: export GRADLE_USER_HOME=D: ...