zoukankan      html  css  js  c++  java
  • POJ1204 Word Puzzles(AC自动机)

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

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

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

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

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<queue>
      4 using namespace std;
      5 #define MAXN 111111
      6 int tn,ch[MAXN][26],flag[MAXN],fail[MAXN],len[MAXN];
      7 void insert(char *s,int k,int l){
      8     int x=0;
      9     for(int i=0; s[i]; ++i){
     10         int y=s[i]-'A';
     11         if(ch[x][y]==0) ch[x][y]=++tn;
     12         x=ch[x][y];
     13     }
     14     flag[x]=k;
     15     len[x]=l;
     16 }
     17 void getFail(){
     18     memset(fail,0,sizeof(fail));
     19     queue<int> que;
     20     for(int i=0; i<26; ++i){
     21         if(ch[0][i]) que.push(ch[0][i]);
     22     }
     23     while(!que.empty()){
     24         int x=que.front(); que.pop();
     25         for(int i=0; i<26; ++i){
     26             if(ch[x][i]) que.push(ch[x][i]),fail[ch[x][i]]=ch[fail[x]][i];
     27             else ch[x][i]=ch[fail[x]][i]; 
     28         }
     29     }
     30 }
     31 
     32 int n,m;
     33 int ansx[1111],ansy[1111],anso[1111];
     34 char str[1111]; int sx[1111],sy[1111];
     35 void match(char o){
     36     int x=0;
     37     for(int i=0; str[i]; ++i){
     38         int y=str[i]-'A';
     39         x=ch[x][y];
     40         int tmp=x;
     41         while(flag[tmp] && tmp){
     42             if(flag[tmp]>0){
     43                 int &idx=flag[tmp];
     44                 ansx[idx]=sx[i-len[tmp]+1];
     45                 ansy[idx]=sy[i-len[tmp]+1];
     46                 anso[idx]=o;
     47                 idx=-1;
     48             }else if(flag[tmp]==-1) break;
     49             tmp=fail[tmp];
     50         }
     51     }
     52 }
     53 char map[1111][11111];
     54 int main(){
     55     int w;
     56     scanf("%d%d%d",&n,&m,&w);
     57     for(int i=0; i<n; ++i) scanf("%s",map[i]);
     58     for(int i=1; i<=w; ++i){
     59         scanf("%s",str);
     60         insert(str,i,strlen(str));
     61     }
     62     getFail();
     63     int sn;
     64     //zero
     65     for(int i=0; i<m; ++i){
     66         for(int j=0; j<n; ++j){
     67             sx[n-j-1]=j; sy[n-j-1]=i;
     68             str[n-j-1]=map[j][i];
     69         }
     70         str[n]=0;
     71         match('A');
     72     }
     73     //one
     74     for(int i=0; i<n; ++i){
     75         int x=i,y=0,sn=0;
     76         while(x>=0 && y<m){
     77             sx[sn]=x; sy[sn]=y;
     78             str[sn++]=map[x][y];
     79             --x; ++y;
     80         }
     81         str[sn]=0;
     82         match('B');
     83     }
     84     for(int i=1; i<m; ++i){
     85         int x=n-1,y=i,sn=0;
     86         while(x>=0 && y<m){
     87             sx[sn]=x; sy[sn]=y;
     88             str[sn++]=map[x][y];
     89             --x; ++y;
     90         }
     91         str[sn]=0;
     92         match('B');
     93     }
     94     //two
     95     for(int i=0; i<n; ++i){
     96         for(int j=0; j<m; ++j){
     97             sx[j]=i; sy[j]=j;
     98             str[j]=map[i][j];
     99         }
    100         str[m]=0;
    101         match('C');
    102     }
    103     //three
    104     for(int i=0; i<m; ++i){
    105         int x=0,y=i,sn=0;
    106         while(x<n && y<m){
    107             sx[sn]=x; sy[sn]=y;
    108             str[sn++]=map[x][y];
    109             ++x; ++y;
    110         }
    111         str[sn]=0;
    112         match('D');
    113     }
    114     for(int i=1; i<n; ++i){
    115         int x=i,y=0,sn=0;
    116         while(x<n && y<m){
    117             sx[sn]=x; sy[sn]=y;
    118             str[sn++]=map[x][y];
    119             ++x; ++y;
    120         }
    121         str[sn]=0;
    122         match('D');
    123     }
    124     //four
    125     for(int i=0; i<m; ++i){
    126         for(int j=0; j<n; ++j){
    127             sx[j]=j; sy[j]=i;
    128             str[j]=map[j][i];
    129         }
    130         str[n]=0;
    131         match('E');
    132     }
    133     //five
    134     for(int i=0; i<m; ++i){
    135         int x=0,y=i,sn=0;
    136         while(x<n && y>=0){
    137             sx[sn]=x; sy[sn]=y;
    138             str[sn++]=map[x][y];
    139             ++x; --y;
    140         }
    141         str[sn]=0;
    142         match('F');
    143     }
    144     for(int i=1; i<n; ++i){
    145         int x=i,y=m-1,sn=0;
    146         while(x<n && y>=0){
    147             sx[sn]=x; sy[sn]=y;
    148             str[sn++]=map[x][y];
    149             ++x; --y;
    150         }
    151         str[sn]=0;
    152         match('F');
    153     }
    154     //six
    155     for(int i=0; i<n; ++i){
    156         for(int j=0; j<m; ++j){
    157             sx[m-j-1]=i; sy[m-j-1]=j;
    158             str[m-j-1]=map[i][j];
    159         }
    160         str[m]=0;
    161         match('G');
    162     }
    163     //seven
    164     for(int i=0; i<m; ++i){
    165         int x=n-1,y=i,sn=0;
    166         while(x>=0 && y>=0){
    167             sx[sn]=x; sy[sn]=y;
    168             str[sn++]=map[x][y];
    169             --x; --y;
    170         }
    171         str[sn]=0;
    172         match('H');
    173     }
    174     for(int i=0; i<n-1; ++i){
    175         int x=i,y=m-1,sn=0;
    176         while(x>=0 && y>=0){
    177             sx[sn]=x; sy[sn]=y;
    178             str[sn++]=map[x][y];
    179             --x; --y;
    180         }
    181         str[sn]=0;
    182         match('H');
    183     }
    184     for(int i=1; i<=w; ++i){
    185         printf("%d %d %c
    ",ansx[i],ansy[i],anso[i]);
    186     }
    187     return 0;
    188 }
  • 相关阅读:
    js 或者 element-ui 将年月日时分秒转换为时间戳
    element-ui 设置table 表头多列显示
    element-ui table 给表头添加icon,以及hover上去的提示文字
    js 获取本周开始结束时间,本月开始结束时间等....
    element-ui Table 翻页后记忆之前勾选
    element-ui 上传图片或视频时,先回显在上传
    element-ui Upload 上传获取当前选择的视频时长
    element-ui 自定义 Upload 上传进度条
    Sqoop(二)常用命令及常数解析
    使用IDEA构建Spring Boot项目简单实例
  • 原文地址:https://www.cnblogs.com/WABoss/p/5244528.html
Copyright © 2011-2022 走看看