刷的第二题AC自动机,这题简直了。。

用询问的串建AC自动机,然后。。。爆搜!

ACBB                  ACBB
ACCA                  A  A
ABBC        ——〉     A  C
ACBA                  ACBA

像这样,将最外面的每一个点将有可能的方向走,比如第一行第一列的A向东南走,就可以得到一个ACBA的串,然后像模板题一样,去匹配找就行了。(老实讲我还是觉得这个很不靠谱。。谁叫人家地图小。。)

小细节,我将查询的字符串反着建ACM了,假设要找ACBA,那我就把它变成ABCA,有什么好处呢?就是找这个串时,我们从最下面的A一路往上,找到最上面的A,这样就可以直接找到起始点了。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int dx[]={-,-,,,,,,-};
const int dy[]={,,,,,-,-,-};
struct Trie
{
bool b;
int s,w[],fail;
}tr[];int trlen;
int a[],len;
void clean(int x)
{
tr[x].s=;tr[x].b=false;tr[x].fail=;
memset(tr[x].w,,sizeof(tr[x].w));
}
void bt(int id)
{
int now=;
for(int i=;i<=len;i++)
{
int x=a[i];
if(tr[now].w[x]==)
{
tr[now].w[x]=++trlen;
clean(trlen);
}
now=tr[now].w[x];
}
tr[now].s=id;
}
int list[];
void bfs()
{
int head=,tail=;list[]=;
while(head!=tail)
{
int now=list[head];
for(int x=;x<=;x++)
{
int son=tr[now].w[x];
if(son==)continue;
if(now==)tr[son].fail=;
else
{
int p=tr[now].fail;
while(p!=&&tr[p].w[x]==)p=tr[p].fail;
tr[son].fail=max(tr[p].w[x],);
}
list[tail]=son;
tail++;if(tail==)tail=;
}
head++;if(head==)head=;
}
}
int n,m,T;
char mp[][],ss[];
struct Ans
{
int x,y,c;
}ans[];
void Find(int x,int y,int i)
{
int now=;
while(x>=&&y>=&&x<n&&y<m)
{
int j=mp[x][y]-'A'+;
while(now!=&&tr[now].w[j]==)now=tr[now].fail;
now=tr[now].w[j];
for(int k=now;k;k=tr[k].fail)
{
if(tr[k].b==false)
{
if(tr[k].s!=)
{
ans[tr[k].s].x=x;
ans[tr[k].s].y=y;
ans[tr[k].s].c=(i+)%;
}
tr[k].b=;
}
}
x+=dx[i];y+=dy[i];
}
}
int main()
{
scanf("%d%d%d",&n,&m,&T);
trlen=;clean();
for(int i=;i<n;i++)scanf("%s",mp[i]);
for(int i=;i<=T;i++)
{
scanf("%s",ss+);len=strlen(ss+);
for(int j=;j<=len;j++)a[j]=ss[len-j+]-'A'+;
bt(i);
}
bfs();
Find(,,);
Find(,m-,);
Find(n-,,);Find(n-,m-,);
for(int j=;j<m;j++)
{
Find(,j,);Find(,j,);Find(,j,);
Find(n-,j,);Find(n-,j,);Find(n-,j,);
}
Find(,,);Find(n-,,);
Find(,m-,);Find(n-,m-,);
for(int i=;i<n;i++)
{
Find(i,,);Find(i,,);Find(i,,);
Find(i,m-,);Find(i,m-,);Find(i,m-,);
}
for(int i=;i<=T;i++)
printf("%d %d %c\n",ans[i].x,ans[i].y,ans[i].c+'A');
return ;
}

caioj1465&&poj1024: 【AC自动机】地图匹配的更多相关文章

  1. hdu 3695:Computer Virus on Planet Pandora(AC自动机,入门题)

    Computer Virus on Planet Pandora Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 256000/1280 ...

  2. [知识点]Trie树和AC自动机

    // 此博文为迁移而来,写于2015年5月27日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w1s8.html 1.前 ...

  3. HDU-4534 郑厂长系列故事——新闻净化 AC自动机+DP

    题意:给定一些单词,这些单词必须要是一个目标串的子串,同时给定一些串,这些串不能够出现在目标串中,其余一些串只会带来不同附加值.现在问满足前两者的情况下,要求附加值最大.数据给定一个原始串,现在要求在 ...

  4. AC自动机基础知识讲解

    AC自动机 转载自:小白 还可参考:飘过的小牛 1.KMP算法: a. 传统字符串的匹配和KMP: 对于字符串S = ”abcabcabdabba”,T = ”abcabd”,如果用T去匹配S下划线部 ...

  5. 【hdu3247-Resource Archiver】位压DP+AC自动机+SPFA

    题意:给定n个文本串,m个病毒串,文本串重叠部分可以合并,但合并后不能含有病毒串,问所有文本串合并后最短多长. (2 <= n <= 10, 1 <= m <= 1000) 题 ...

  6. hdoj 3065 病毒侵袭持续中(AC自动机)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 思路分析:问题需要模式匹配多个模式串,需要注意的是模式串会包含和重叠,需要对AC自动机的匹配过 ...

  7. poj_2778_DNA Sequence(AC自动机+矩阵)

    题目链接:poj_2778_DNA Sequence 题意: 有m个模式串,然后给你一个长度n,问你n长度的DNA序列有多少种不包含这m个模式串 题解: 这题显然要用AC自动机,将模式串的AC自动机建 ...

  8. hdu_2457_DNA repair(AC自动机+DP)

    题目连接:hdu_2457_DNA repair 题意: 给你N个字符串,最后再给你一个要匹配的串,问你最少修改多少次,使得这个串不出现之前给的N的字符串 题解: 刚学AC自动机,切这题还真不知道怎么 ...

  9. AC自动机算法小结

    AC自动机,可惜不能自动AC 转载:飘过的小牛 OIer55242 简介 Aho-Corasick automation 该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一.一个常见的例子就 ...

  10. Aho-Corasick automaton(AC自动机)解析及其在算法竞赛中的典型应用举例

    摘要: 本文主要讲述了AC自动机的基本思想和实现原理,如何构造AC自动机,着重讲解AC自动机在算法竞赛中的一些典型应用. 什么是AC自动机? 如何构造一个AC自动机? AC自动机在算法竞赛中的典型应用 ...

随机推荐

  1. vue项目实战, webpack 配置流程记录

    vue项目实战记录,地址在这 购物车单界面 npm install npm run dev 跑起来可以看到界面效果 这里简单记录一下webpack的编译流程 入口 package.json " ...

  2. Spring boot+Spring Security 4配置整合实例

    本例所覆盖的内容: 1. 使用Spring Security管理用户身份认证.登录退出 2. 用户密码加密及验证 3. 采用数据库的方式实现Spring Security的remember-me功能 ...

  3. 无记录时显示gridview表头,并增加一行显示“没有记录”【绑定SqlDataSource控件时】

    原文发布时间为:2008-08-04 -- 来源于本人的百度文章 [由搬家工具导入] using System;using System.Data;using System.Configuration ...

  4. POJ 3104 Drying [二分 有坑点 好题]

    传送门 表示又是神题一道 Drying Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9327   Accepted: 23 ...

  5. golang并发编程goroutine+channel(一)

    go语言的设计初衷除了在不影响程序性能的情况下减少复杂度,另一个目的是在当今互联网大量运算下,如何让程序的并发性能和代码可读性达到极致.go语言的并发关键词 "go" go dos ...

  6. 表单form-input标签禁止聚焦输入

    1.input标签禁止聚焦输入(针对小程序) <input type="text" disabled /> input标签禁止聚焦输入(针对网页html) 1).< ...

  7. (47)C#运行时序列化

    序列化是将对象或对象图转化成字节流的过程.反序列化是将字节流转换回对象图的过程.

  8. Java中的网络基础

    先来一张图记录一下大概思路,之后再更新具体的代码实现.基本上来说,前半部分自己会编写一个基于socket编程的多客户端dos聊天服务器,后半部分可以实现与已有的一些服务器(比如www.google.c ...

  9. 求菲波那契数列的第n个数

    1,2,3,5,8,13..... 求第n个数 def get_num(n): if n == 1: return 1 if n == 2: return 2 return get_num(n - 1 ...

  10. table合并单元格

    table合并单元格 新建一张表格.要求表格有四行四列,当中第一行的四列合并,第二行.第三行和第四行的第一列合并 <!DOCTYPE html PUBLIC "-//W3C//DTD ...