poj 1204 字符串处理 多串匹配自动机

View Code
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<stdlib.h>
  4 #define N 1010
  5 struct node
  6 {
  7        node *next[26];
  8        node *fail;
  9        int count,index;
 10        node()
 11        {
 12             count=0,index=0,fail=NULL;
 13             for(int i=0;i<26;i++)next[i]=NULL;
 14        }
 15 }*root,*q[501000];
 16 int head,tail;
 17 int n,m,w,sum,x[N],y[N];
 18 char map[N][N];
 19 char str[N],dir[N];
 20 int len[N];
 21 int h[8]={-1,-1,0,1,1,1,0,-1};
 22 int c[8]={0,1,1,1,0,-1,-1,-1};
 23 void insert(int ii)
 24 {
 25      int i=0,index;
 26      node *temp=root;
 27      len[ii]=strlen(str);
 28      while(str[i])
 29      {
 30            index=str[i]-'A';
 31            if(temp->next[index]==NULL)temp->next[index]=new node();
 32            temp=temp->next[index];
 33            i++;
 34      }
 35      temp->count=1;
 36      temp->index=ii;
 37 }
 38 void build_ac()
 39 {
 40      node *temp,*p;
 41      head=tail=0;
 42      q[head++]=root;
 43      while(head!=tail)
 44      {
 45            temp=q[tail++];
 46            for(int i=0;i<26;i++)
 47            {
 48                if(temp->next[i]!=NULL)
 49                {
 50                    if(temp==root)temp->next[i]->fail=root;
 51                    else
 52                    {
 53                        p=temp->fail;
 54                        while(p!=NULL)
 55                        {
 56                              if(p->next[i]!=NULL)
 57                              {
 58                                 temp->next[i]->fail=p->next[i];
 59                                 break;
 60                              }
 61                              p=p->fail;
 62                        }
 63                        if(p==NULL)temp->next[i]->fail=root;
 64                    }
 65                    q[head++]=temp->next[i];
 66                }
 67            }
 68      }
 69 }
 70 bool Is_OK(int x,int y)
 71 {
 72      if(x>=n||x<0||y<0||y>=m)
 73         return false;
 74      return true;
 75 }
 76 void query(int i,int j,int k)
 77 {
 78      int cx=i,cy=j,ind;
 79      node *temp=root,*p;
 80      for(;Is_OK(cx,cy);cx+=h[k],cy+=c[k])
 81      {
 82           ind=map[cx][cy]-'A';
 83           printf("%d\n",ind);
 84           while(temp->next[ind]==NULL&&temp!=root)
 85           {
 86                 temp=temp->fail;
 87                 
 88           }
 89           temp=temp->next[ind];
 90           p=(temp==NULL)?root:temp;
 91           while(p!=root)
 92           {
 93                 if(p->count)
 94                 {
 95                    sum++;
 96                    p->count=0;
 97                    x[p->index]=cx-(h[k]*len[p->index]);
 98                    y[p->index]=cy-(c[k]*len[p->index]);
 99                    dir[p->index]='A'+k;
100                 }
101                 p=p->fail;
102           }
103      }
104 }
105 void solution()
106 {
107      for(int i=0;i<n&&sum<w;i++)
108      {
109          query(i,0,1);query(i,0,2);query(i,0,3);
110          query(i,m-1,5);query(i,m-1,6);query(i,m-1,7);
111      }
112      for(int i=0;i<m&&sum<w;i++)
113      {
114          query(0,i,3);query(0,i,4);query(0,i,5);
115          query(n-1,i,0);query(n-1,i,1);query(n-1,i,7);
116      }
117 }
118 int main()
119 {
120     while(~scanf("%d%d%d",&n,&m,&w))
121     {
122          root=new node();
123          for(int i=0;i<n;i++)
124              scanf("%s",map[i]);
125          sum=0;
126          for(int i=0;i<w;i++)
127          {
128              scanf("%s",str);
129              insert(i+1);
130          }
131          build_ac();
132          solution();
133          for(int i=1;i<=w;i++)
134              printf("%d %d %c\n",x[i],y[i],dir[i]);
135 
136     }
137     return 0;
138 }

 

题意:

告诉你一篇文章,也就是一个nxm的字符矩阵,然后给你w个单词,问这些单词在文章中出现的位置,输出坐标,然后现在有八个方向。

同时还要在输出的坐标位置后面输出相应的匹配方向。

为了节省时间,我们肯定首先要建立一个字典树。

然后做法有两种,一种是直接从文章中的每一个点出发从八个方向,在字典树当中比较。

一种是建立ac自动机,构建字典树当中的fail指针,从文章的边界出发,将所有的能匹配的方向都扫一遍就ok了。。。

字典树做法:

View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 #define N 1010
 4 struct node
 5 {
 6        node *next[26];
 7        int count,index;
 8        node()
 9        {
10            count=0,index=0;
11            for(int i=0;i<26;i++)next[i]=NULL;
12        }
13 }*root;
14 char map[N][N];
15 char str[N];
16 int n,m,w,sum;
17 int x[N],y[N];
18 char dir[N];
19 int h[8]={-1,-1,0,1,1,1,0,-1};
20 int c[8]={0,1,1,1,0,-1,-1,-1};
21 void insert(int ii)
22 {
23      node *p=root;
24      int i=0;
25      while(str[i])
26      {
27            int ind=str[i]-'A';
28            if(p->next[ind]==NULL)p->next[ind]=new node();
29            p=p->next[ind];
30            i++;
31      }
32      p->count=1;
33      p->index=ii;
34 }
35 bool Is_OK(int x,int y)
36 {
37      if(x>=0&&x<n&&y>=0&&y<m)
38      return true;
39      return false;
40 }
41 void query(int i,int j,int k)
42 {
43       int cx=i,cy=j,index;
44       node *temp=root,*p;
45       for(;Is_OK(cx,cy);cx+=h[k],cy+=c[k])
46       {
47           index=map[cx][cy]-'A';
48           if(temp->next[index]==NULL)
49              return ;
50           temp=temp->next[index];
51           if(temp->count)
52           {
53              sum++;
54              x[temp->index]=i;
55              y[temp->index]=j;
56              dir[temp->index]='A'+k;
57              temp->count=0;
58           }
59       }
60 }
61 void solution()
62 {
63      for(int i=0;i<n;i++)
64      {
65          for(int j=0;j<m;j++)
66          {
67             for(int k=0;k<8;k++)
68             {
69                query(i,j,k);
70                if(sum==w)break;
71             }
72             if(sum==w)break;
73          }
74          if(sum==w)break;
75      }
76 }
77 int main()
78 {
79     while(~scanf("%d%d%d",&n,&m,&w))
80     {
81         root=new node();
82         for(int i=0;i<n;i++)
83             scanf("%s",map[i]);
84         for(int i=0;i<w;i++)
85         {
86             scanf("%s",str);
87             insert(i+1);
88         }
89         sum=0;
90         solution();
91         for(int i=1;i<=w;i++)
92             printf("%d %d %c\n",x[i],y[i],dir[i]);
93     }
94     return 0;
95 }

ac自动机:

 

posted @ 2013-03-02 12:47  诺小J  阅读(148)  评论(0编辑  收藏  举报