【AC自动机】地图匹配
来源:互联网 发布:张玮 high 知乎 编辑:程序博客网 时间:2024/06/04 22:59
hz2016评测《《点击访问《《增加了内存caioj《《点击访问这题其实还是模版题吧,说难不难,说不难还是很难。我们不能按照暴力的思想,给图for8个方向建树。这样会超时的。所以悲伤的我们只好测试可不可以反着建。最后我们总结出反着建句子的字典树,然后离线找匹配。例如一个5*5的地图1111112221123211222111111先在1号的点向八个方向去字符树里面匹配然后就是2的点,最后3号点,总会匹配到适合的字符串。所以这题就解出来了。#include<map>#include<queue>#include<cmath>#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#define Maxchar 1000000#define Maxm 1000#define Maxn 1000#define Maxs 26#define mes(x,y) memset(x,y,sizeof(x));#define mpy(x,y) memcpy(x,y,sizeof(x))#define INF 2147483647using namespace std;const int dx[8]={-1,-1,0,1,1,1,0,-1};const int dy[8]={0,1,1,1,0,-1,-1,-1};struct Tire{int s,fail,c[Maxs+1];bool v;void clear(){s=fail=0;v=false;mes(c,-1);}}tr[Maxm*Maxm+1];int tot;char s[Maxn+1];struct node{int x,y,w;}a[Maxn+1];map<int, map<int,int> >qt;void add(int root,int p) {int x=root,len=strlen(s+1);for(int i=len;i>=1;i--){int y=s[i]-'A'+1; if(tr[x].c[y]==-1){tr[x].c[y]=++tot;tr[tot].clear();}x=tr[x].c[y];}tr[x].s=p;}queue<int> q;void build_fail(){int x,y,son;q.push(0);while(q.empty()==false) {x=q.front();for(int i=1;i<=26;i++){son=tr[x].c[i];if(son==-1)continue;if(x==0)tr[son].fail=0;else{int j=tr[x].fail;while(j>0&&tr[j].c[i]==-1)j=tr[j].fail;tr[son].fail=max(tr[j].c[i],0);}q.push(son);}q.pop();}}int n,m,member;char maps[Maxm+1][Maxm+1];inline bool check(int x,int y){if(x>=1&&x<=n&&y>=1&&y<=m)return true;return false;}void Find(int x,int y,int w){int m=0;while(check(x,y)==true){int j=maps[x][y]-'A'+1;while(m!=0&&tr[m].c[j]==-1)m=tr[m].fail;if(tr[m].c[j]!=-1)m=tr[m].c[j];for(int k=m;k!=0&&tr[k].v==false;k=tr[k].fail){if(tr[k].s>0){int l=tr[k].s;a[l].x=x;a[l].y=y;a[l].w=(w+4)%8;}tr[k].v=true;}x+=dx[w];y+=dy[w];}}int main(){scanf("%d%d%d",&n,&m,&member);tr[0].clear();tot=0;for(int i=1;i<=n;i++)scanf("%s",maps[i]+1);for(int i=1;i<=member;i++){scanf("%s",s+1);add(0,i);}build_fail();for(int i=1;i<=n;i++)Find(i,1,1),Find(i,1,2),Find(i,1,3),Find(i,m,5),Find(i,m,6),Find(i,m,7);for(int j=1;j<=m;j++)Find(1,j,3),Find(1,j,4),Find(1,j,5),Find(n,j,0),Find(n,j,1),Find(n,j,7);for(int i=1;i<=member;i++)printf("%d %d %c\n",a[i].x-1,a[i].y-1,a[i].w+'A');return 0;}
查看原文:http://hz2016.tk/blog/?p=41
阅读全文
0 0
- 【AC自动机】地图匹配
- [poj1204][caioj1465][AC自动机]地图匹配
- poj1204Word Puzzles,caioj1465地图匹配(AC自动机+搜索)
- 字符串匹配-AC自动机
- AC自动机通配符匹配
- AC自动机通配符匹配
- AC自动机匹配
- 多串匹配-AC自动机
- 多串匹配 AC自动机
- AC自动机(多模串匹配)
- 【AC自动机+DP】匹配(match)
- 字符串匹配之AC自动机
- 数据结构-字符串匹配AC自动机
- 多模式匹配--AC自动机算法
- AC自动机(多模式匹配)
- AC自动机 多字符串匹配 code
- AC自动机(矩阵匹配)uva11019
- ac自动机实现多模式匹配
- 最短路条数模板
- 全排列 (递归版)Java版
- 我的博客网站开通了
- fudandemo
- 控制不好情绪,读这9句话
- 【AC自动机】地图匹配
- 51nod 1791 合法括号子段 (dp)
- vue-cli 脚手架
- Django REST framework-教程00-quickstart原创翻译
- Spring入门笔记(五)@Autowired注解
- 升序单链表删除重复值,输出
- rocoo hotfix之后进App卡住
- Leetcode之Search for a Range 问题
- 求二叉树的深度