zoukankan      html  css  js  c++  java
  • poj1204

    一开始做这道题没什么头绪,那时只会写Trie,ac自动机不怎么懂。后来在discuss里看到要用AC自动机做。

    先把要查询的字符串添加进Trie图里,建完自动机后再从矩形四周八个方向依次查询,结果放在数组里。

      1 #include<cstdio>
      2 #include<string.h>
      3 #include<iostream>
      4 #include<queue>
      5 using namespace std;
      6 const int maxn=1001;
      7 char g[maxn][maxn],T[maxn][maxn],str[maxn];
      8 int ch[maxn*maxn][26],val[maxn*maxn],f[maxn*maxn],last[maxn*maxn],vis[maxn];
      9 int L,C,W,top,ans[maxn][4];
     10 int dir[][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
     11 void init()
     12 {
     13     top=1;
     14     memset(ch[0],0,sizeof(ch[0]));
     15     memset(ans,0,sizeof(ans));
     16 }
     17 int idx(char c)
     18 {
     19     return c-'A';
     20 }
     21 void insert(char *s,int op)
     22 {
     23     int u=0,n=strlen(s),c;
     24     for(int i=0;i<n;i++)
     25     {
     26         c=idx(s[i]);
     27         if(ch[u][c]==0)
     28         {
     29             memset(ch[top],0,sizeof(ch[top]));
     30             val[top]=0;
     31             ch[u][c]=top++;
     32         }
     33         u=ch[u][c];
     34     }
     35     val[u]=op+1;
     36     //printf("val=%d\n",val[u]);
     37 }
     38 
     39 void getfail()
     40 {
     41     queue<int> q;
     42     f[0]=0;
     43     for(int c=0;c<26;c++)
     44     {
     45         int u=ch[0][c];
     46         if(u){f[u]=0;q.push(u);last[u]=0;}
     47     }
     48     while(!q.empty())
     49     {
     50         int r=q.front();q.pop();
     51         for(int c=0;c<26;c++)
     52         {
     53             int u=ch[r][c];
     54             if(!u) continue;
     55             q.push(u);
     56             int v=f[r];
     57             while(v&&!ch[v][c]) v=f[v];
     58             f[u]=ch[v][c];
     59             last[u]=val[f[u]]?f[u]:last[f[u]];
     60         }
     61     }
     62 }
     63 
     64 bool ok(int x,int y)
     65 {
     66     return (x>=0&&x<L&&y>=0&&y<C);
     67 }
     68 
     69 void print(int j,int pos,int x,int y,int d)
     70 {
     71     //printf("j=%d d=%d x=%d y=%d ",j,d,x,y);
     72     int n=strlen(T[j]);
     73     int i;
     74     //printf("%d")
     75     n=pos-n;
     76     //printf("n=%d pos=%d ",n,pos);
     77     int nx=x,ny=y;
     78     for(i=0;i<=n;i++)
     79     {
     80         nx+=dir[d][0];
     81         ny+=dir[d][1];
     82     }
     83     //printf("nx=%d ny=%d\n",nx,ny);
     84     ans[j][0]=nx;
     85     ans[j][1]=ny;
     86     ans[j][2]=d;
     87 }
     88 void find(char *T,int x,int y,int d)
     89 {
     90     int n=strlen(T);
     91     int i,j=0;
     92     for(i=0;i<n;i++)
     93     {
     94         int c=T[i]-'A';
     95         while(j&&!ch[j][c]) j=f[j];
     96         j=ch[j][c];
     97         if(val[j]) print(val[j]-1,i,x,y,d);
     98         else if(last[j]) print(val[last[j]]-1,i,x,y,d);
     99     }
    100 }
    101 void make(int x,int y,int d)
    102 {
    103     int nx=x,ny=y,j=0;
    104     while(ok(nx,ny))
    105     {
    106         str[j++]=g[nx][ny];
    107         nx+=dir[d][0];
    108         ny+=dir[d][1];
    109     }
    110     str[j]='\0';
    111     find(str,x,y,d);
    112 }
    113 void work()
    114 {
    115     getfail();
    116     memset(vis,0,sizeof(vis));
    117     int i,j;
    118     for(i=0;i<L;i++)
    119     {
    120         for(j=0;j<8;j++)
    121         {
    122             make(i,0,j);
    123             make(i,C-1,j);
    124         }
    125     }
    126     for(i=0;i<C;i++)
    127     {
    128         for(j=0;j<8;j++)
    129         {
    130             make(0,i,j);
    131             make(L-1,i,j);
    132         }
    133     }
    134 }
    135 
    136 
    137 int main()
    138 {
    139     //freopen("test.txt","r",stdin);
    140     scanf("%d%d%d",&L,&C,&W);
    141     int i,j;
    142     getchar();
    143     init();
    144     for(i=0;i<L;i++)
    145     scanf("%s",g[i]);
    146     for(i=0;i<W;i++)
    147     {
    148         scanf("%s",T[i]);
    149         insert(T[i],i);
    150     }
    151     work();
    152     for(i=0;i<W;i++)
    153     {
    154         printf("%d %d %c\n",ans[i][0],ans[i][1],ans[i][2]+'A');
    155     }
    156     return 0;
    157 }
    View Code
  • 相关阅读:
    由自身经历谈“不谋全局者,不足以谋一域”
    MySQL 常用SQL语句
    举例说明android中ListPreference的使用方法
    cookie机制和session机制的区别
    thinkphp浏览历史功能实现方法
    利用PHP获取访客IP、地区位置、浏览器及来源页面等信息
    PHP+Ajax点击加载更多内容 -这个效果好,速度快,只能点击更多加载,不能滚动自动加载...
    php用正则表达式匹配URL的简单方法(亲测可行)
    PHP实现记录浏览历史页面
    [译] 流言终结者 —— “SQL Server 是Sybase的产品而不是微软的”
  • 原文地址:https://www.cnblogs.com/longlongagocsu/p/3093599.html
Copyright © 2011-2022 走看看