zoukankan      html  css  js  c++  java
  • poj 1204

    AC自动机的应用,第一次做ac自动机,磕磕碰碰做了一整天,之前对于AC自动机的原理就想了好几个星期,一直没想透彻,失配函数还行,就是那个匹配过程不是很透彻,昨天又想了想,突然感觉理解了,但今天发现有些细节还是没搞透彻,唉╮(╯▽╰)╭ 。

    思路就是枚举每个方向的字符串通过利用AC自动机进行匹配,610ms水过

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <queue>
      5 using namespace std;
      6 const int maxn=1000+10;
      7 char s[maxn][maxn];
      8 int ch[maxn*300][26],val[maxn*300],f[maxn*300],location[maxn][2],len[maxn],rd[maxn],last[maxn*300];
      9 int dir[8][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
     10 char dm[8]={'A','B','C','D','E','F','G','H'};
     11 int l,c,w,tot;
     12 void Insert(char * ts,int x)
     13 {
     14     int i,len=strlen(ts),u=0,loc;
     15     for(i=0;i<len;i++)
     16     {
     17         loc=ts[i]-'A';
     18         if(!ch[u][loc])
     19             ch[u][loc]=++tot;
     20         u=ch[u][loc];
     21     }
     22     val[u]=x;
     23 }
     24 void  getFail()
     25 {
     26     queue<int> q;
     27     int i,u;
     28     f[0]=0;
     29     for(i=0;i<26;i++)
     30     {
     31         u=ch[0][i];
     32         if(u)
     33         {
     34             f[u]=0;
     35             last[u]=0;
     36             q.push(u);
     37         }
     38     }
     39     int fr,j;
     40     while(!q.empty())
     41     {
     42         fr=q.front();q.pop();
     43         for(i=0;i<26;i++)
     44         {
     45             u=ch[fr][i];
     46             if(!u)
     47             {
     48                 ch[fr][i]=ch[f[fr]][i];//意思就是说失配了
     49                 continue;
     50             }
     51             q.push(u);
     52             j=f[fr];
     53             while(j&&!ch[fr][i]) j=f[fr];
     54             f[u]=ch[j][i];
     55             last[u]=val[f[u]]?f[u]:last[f[u]];
     56         }
     57     }
     58 }
     59 void getL(int j,int x,int y,int d)
     60 {
     61     if(j)
     62     {
     63         int t=val[j];
     64         rd[t]=d;
     65         location[t][0]=x-(len[t]-1)*dir[d][0];
     66         location[t][1]=y-(len[t]-1)*dir[d][1];
     67         getL(last[j],x,y,d);
     68     }
     69 }
     70 void solve(int x,int y,int d)
     71 {
     72     int tc,j=0;
     73     for(;x>=0&&x<l&&y>=0&&y<c;x+=dir[d][0],y+=dir[d][1])
     74     {
     75        tc=s[x][y]-'A';
     76         j=ch[j][tc];
     77         if(val[j]) getL(j,x,y,d);
     78         else if(last[j]) getL(last[j],x,y,d);
     79     }
     80 }
     81 int main()
     82 {
     83     char ts[maxn];
     84     scanf("%d%d%d",&l,&c,&w);
     85     int i;
     86     for(i=0;i<l;i++) scanf("%s",s[i]);
     87     for(i=1;i<=w;i++)
     88     {
     89         scanf("%s",ts);
     90         len[i]=strlen(ts);
     91         Insert(ts,i);
     92     }
     93     getFail();
     94     for(i=0;i<l;i++)
     95     {
     96         solve(i,0,1);
     97         solve(i,0,2);
     98         solve(i,0,3);
     99         solve(i,c-1,5);
    100         solve(i,c-1,6);
    101         solve(i,c-1,7);
    102     }
    103     for(i=0;i<c;i++)
    104     {
    105         solve(0,i,3);
    106         solve(0,i,4);
    107         solve(0,i,5);
    108         solve(l-1,i,0);
    109         solve(l-1,i,1);
    110         solve(l-1,i,7);
    111     }
    112     for(i=1;i<=w;i++)
    113         printf("%d %d %c\n",location[i][0],location[i][1],dm[rd[i]]);
    114     return 0;
    115 }

    ---恢复内容结束---

  • 相关阅读:
    spark 脚本示例
    R树的应用
    将博客搬至CSDN
    select
    注册页面的验证码的实现
    web项目.注册及登陆
    eclipse web 项目中遇到的问题总结
    Apache与Tomcat
    关于MVC整理
    JDBC
  • 原文地址:https://www.cnblogs.com/lj030/p/3078401.html
Copyright © 2011-2022 走看看