您的位置:首页 > 其它

POJ 1204-Word Puzzles解题报告

2013-03-14 20:28 337 查看
确实是一道字符串好题,用AC自动机做的,不过思路比较简单,并且AC自动机还要加一些优化,要找的是串是否出现在了模式串中,这样有很多位置不用去比较,比如说,要考虑一行的时候,这一行的子串就不用再次验证了,因为出现在了这一行的一部分中一定会出现在整个这一行中的,这样能减少处理时间

View Code

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define N 1005
struct node
{
bool istail;
node *next[26],*fail;
int id;
}qq[100005],*que[100005];
node *rt = new node();
char key
;
int len
;
int dix[8][2] = {-1,0,-1,1,0,1,1,1,1,0,1,-1,0,-1,-1,-1};
char res[9] = {"ABCDEFGH"};
struct pos
{
int x,y,dis;
};
pos ans
;
char mes

;
int k;
void insert(char *str,int id)
{
int i;
int temp;
node *p = rt;
for(i = 0;str[i]; i++)
{
temp = str[i] - 'A';
if(p->next[temp] == NULL)
{
qq[k].istail = false;
qq[k].fail = NULL;
memset(qq[k].next,NULL,sizeof(qq[k].next));
p->next[temp] = &qq[k++];
}
p = p->next[temp];
}
p->istail = true;
p->id = id;
}
void ac()
{
int f = 0,r = 0;
int i;
node *p,*temp;
rt->fail = NULL;
que[r++] = rt;
while(f < r)
{
temp = que[f++];
for(i = 0;i < 26;i++)
{
if(temp->next[i] == NULL)
continue;
if(temp == rt)
temp->next[i]->fail = rt;
else
{
for(p = temp->fail; p != NULL; p = p->fail)
{
if(p->next[i] != NULL)
{
temp->next[i]->fail = p->next[i];
break;
}
}
if(p == NULL)
{
temp->next[i]->fail = rt;
}
}
que[r++] = temp->next[i];
}
}
}
void query(int x,int y,int i)
{
int tem;
int nx = x,ny = y;
node *p,*q;
p = rt;
for(;mes[x][y];x += dix[i][0],y += dix[i][1])
{
tem = mes[x][y] - 'A';
while(p->next[tem] == NULL &&p != rt)
p = p->fail;
p = p->next[tem];
if(p == NULL)
p = rt;
q = p;
while(q != rt)
{
if(q->istail)
{
q->istail = false;
ans[q->id].x = x - dix[i][0] * (len[q->id] - 1) - 1;
ans[q->id].y = y - dix[i][1] * (len[q->id] - 1) - 1;
ans[q->id].dis = i;
}
q = q->fail;
}
}
}
int main()
{
int r,c,m;
int i,j;
for(i = 0;i < 26; i++)
rt->next[i] = NULL;
memset(mes,0,sizeof(mes));
scanf("%d%d%d",&r,&c,&m);
for(i = 1;i <= r; i++)
scanf("%s",mes[i]+1);
for(i = 0;i < m;i++)
{
scanf("%s",key);
len[i] = strlen(key);
insert(key,i);
}
ac();
for(i = 1;i <= r; i++)
{
query(i,1,1),query(i,1,2),query(i,1,3);
query(i,c,5),query(i,c,6),query(i,c,7);
}
for(i = 1;i <= c; i++)
{
query(1,i,3),query(1,i,4),query(1,i,5);
query(r,i,1),query(r,i,0),query(r,i,7);
}
for(i = 0;i < m;i++)
printf("%d %d %c\n",ans[i].x,ans[i].y,res[ans[i].dis]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: