给一个L*C字符矩阵和W个字符串,问那些字符串出现在矩阵的位置,横竖斜八个向。

就是个多模式匹配的问题,直接AC自动机搞了,枚举字符矩阵八个方向的所有字符串构成主串,然后在W个模式串构造的AC自动机上跑。

另外,temp指针的那个找遗漏后缀的过程执行时标记一下,下一次再到这个结点就不需要再进行一次temp的过程,这样的时间复杂度就是O(W个模式串总长+LC)。

一开始还想8个方向分别计算坐标= =写第二个方向懒得写了,然后就忽然想到可以一开始构造主串时就存坐标。。最后代码很是挺长的。。

 #include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define MAXN 111111
int tn,ch[MAXN][],flag[MAXN],fail[MAXN],len[MAXN];
void insert(char *s,int k,int l){
int x=;
for(int i=; s[i]; ++i){
int y=s[i]-'A';
if(ch[x][y]==) ch[x][y]=++tn;
x=ch[x][y];
}
flag[x]=k;
len[x]=l;
}
void getFail(){
memset(fail,,sizeof(fail));
queue<int> que;
for(int i=; i<; ++i){
if(ch[][i]) que.push(ch[][i]);
}
while(!que.empty()){
int x=que.front(); que.pop();
for(int i=; i<; ++i){
if(ch[x][i]) que.push(ch[x][i]),fail[ch[x][i]]=ch[fail[x]][i];
else ch[x][i]=ch[fail[x]][i];
}
}
} int n,m;
int ansx[],ansy[],anso[];
char str[]; int sx[],sy[];
void match(char o){
int x=;
for(int i=; str[i]; ++i){
int y=str[i]-'A';
x=ch[x][y];
int tmp=x;
while(flag[tmp] && tmp){
if(flag[tmp]>){
int &idx=flag[tmp];
ansx[idx]=sx[i-len[tmp]+];
ansy[idx]=sy[i-len[tmp]+];
anso[idx]=o;
idx=-;
}else if(flag[tmp]==-) break;
tmp=fail[tmp];
}
}
}
char map[][];
int main(){
int w;
scanf("%d%d%d",&n,&m,&w);
for(int i=; i<n; ++i) scanf("%s",map[i]);
for(int i=; i<=w; ++i){
scanf("%s",str);
insert(str,i,strlen(str));
}
getFail();
int sn;
//zero
for(int i=; i<m; ++i){
for(int j=; j<n; ++j){
sx[n-j-]=j; sy[n-j-]=i;
str[n-j-]=map[j][i];
}
str[n]=;
match('A');
}
//one
for(int i=; i<n; ++i){
int x=i,y=,sn=;
while(x>= && y<m){
sx[sn]=x; sy[sn]=y;
str[sn++]=map[x][y];
--x; ++y;
}
str[sn]=;
match('B');
}
for(int i=; i<m; ++i){
int x=n-,y=i,sn=;
while(x>= && y<m){
sx[sn]=x; sy[sn]=y;
str[sn++]=map[x][y];
--x; ++y;
}
str[sn]=;
match('B');
}
//two
for(int i=; i<n; ++i){
for(int j=; j<m; ++j){
sx[j]=i; sy[j]=j;
str[j]=map[i][j];
}
str[m]=;
match('C');
}
//three
for(int i=; i<m; ++i){
int x=,y=i,sn=;
while(x<n && y<m){
sx[sn]=x; sy[sn]=y;
str[sn++]=map[x][y];
++x; ++y;
}
str[sn]=;
match('D');
}
for(int i=; i<n; ++i){
int x=i,y=,sn=;
while(x<n && y<m){
sx[sn]=x; sy[sn]=y;
str[sn++]=map[x][y];
++x; ++y;
}
str[sn]=;
match('D');
}
//four
for(int i=; i<m; ++i){
for(int j=; j<n; ++j){
sx[j]=j; sy[j]=i;
str[j]=map[j][i];
}
str[n]=;
match('E');
}
//five
for(int i=; i<m; ++i){
int x=,y=i,sn=;
while(x<n && y>=){
sx[sn]=x; sy[sn]=y;
str[sn++]=map[x][y];
++x; --y;
}
str[sn]=;
match('F');
}
for(int i=; i<n; ++i){
int x=i,y=m-,sn=;
while(x<n && y>=){
sx[sn]=x; sy[sn]=y;
str[sn++]=map[x][y];
++x; --y;
}
str[sn]=;
match('F');
}
//six
for(int i=; i<n; ++i){
for(int j=; j<m; ++j){
sx[m-j-]=i; sy[m-j-]=j;
str[m-j-]=map[i][j];
}
str[m]=;
match('G');
}
//seven
for(int i=; i<m; ++i){
int x=n-,y=i,sn=;
while(x>= && y>=){
sx[sn]=x; sy[sn]=y;
str[sn++]=map[x][y];
--x; --y;
}
str[sn]=;
match('H');
}
for(int i=; i<n-; ++i){
int x=i,y=m-,sn=;
while(x>= && y>=){
sx[sn]=x; sy[sn]=y;
str[sn++]=map[x][y];
--x; --y;
}
str[sn]=;
match('H');
}
for(int i=; i<=w; ++i){
printf("%d %d %c\n",ansx[i],ansy[i],anso[i]);
}
return ;
}

POJ1204 Word Puzzles(AC自动机)的更多相关文章

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

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

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

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

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

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

  4. poj1204 Word Puzzles

    Word Puzzles Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 12090   Accepted: 4547   S ...

  5. POJ 1204 Word Puzzles | AC 自动鸡

    题目: 给一个字母矩阵和几个模式串,矩阵中的字符串可以有8个方向 输出每个模式串开头在矩阵中出现的坐标和这个串的方向 题解: 我们可以把模式串搞成AC自动机,然后枚举矩阵最外围一层的每个字母,向八个方 ...

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

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

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

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

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

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

  9. poj1204之AC自动机

    Word Puzzles Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 8235   Accepted: 3104   Sp ...

随机推荐

  1. 对于(function(){}())和function(){}实例的作用域分析(里面有很多问题……)

    今天在群里看到一个问题,让我纠结了好一会.下面是我的分析,感觉里面还有很多问题,关于作用域还是不太理解,希望大家看到问题第一时间反馈给我,看到实在受不了的地方说几句都没关系,谢谢. 请看题: 1.对象 ...

  2. First Missing Positive

    不好想,用桶排序解决. int findMissingPostive(int A[], int n) { bucket_sort(A, n); ; i < n; i++) ) ; ; } voi ...

  3. puppet之自定义fact(转载)

    1.使用环境变量'FACTERLIB'创建fact 1.1.在自定义目录里面定义一个fact,列出当前系统登录的用户数 [root@agent1 ~]# vim /var/lib/puppet/kis ...

  4. Unable to mount the CD/DVD image virtualbox解决方法

    转自: http://askubuntu.com/questions/321589/unable-to-mount-the-cd-dvd-image-on-the-machine-sandbox

  5. 【云计算】Docker Nginx示例

    使用数据卷容器,配置Nginx Docker作为静态文件服务器 . 该方法是直接使用命令行,当然也可使用Dockerfile文件进行创建. 其实,使用docker创建nginx容器是很简单的,但要和数 ...

  6. eclipse debug source not fount

    1.选择Edit Source Lookup Path 2.选择Add 3.选择Java Project 4.选择相应的Project 进行OK确定即可 注意:做完以上的操作,要清除一下原来的断点,然 ...

  7. wx.html2.WebView在 target="_blank" or rel="external" 没有反映的解决方法

    在wx.html2.EVT_WEBVIEW_LOADED中,用WebView.RunScript运行删除链接目标的脚本 javaScriptStr = '''function deleteBlank( ...

  8. Java for LeetCode 073 Set Matrix Zeroes

    Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. 解题思路: ...

  9. 解决Unable to reach a settlement: [diffie-hellman-group1-sha1, diffie-hellman-group-exchange-sha1] and [curve25519-sha256@li

    SharpSSH或JSCH使用diffie-hellman-group1-sha1和diffie-hellman-group-exchange-sha1密钥交换算法,而OpenSSH在6.7p1版本之 ...

  10. fedora 损坏,开机出现GRUB 2 启动提示符

    如果设置不当,GRUB 2 可能会加载失败,随后进入启动提示符中.要解决此问题,按如下步骤执行: 1. 列出 GRUB 2 识别的驱动器: grub2> ls 2. 对于一个含有三个分区的 do ...