• poj 1204


    http://poj.org/problem?id=1204

    大意:给出一个棋盘puzzle,,和w个模式串,,在棋盘中寻找模式串。。棋盘中任意一格有8个方向可以走。。

    解题思路: AC自动机 + 枚举8个方向即可

    get_trie(),get_ac().直接用模版。。。。

    query 有一点小技巧。。需要枚举8个方向,,对于一行,我们对竖直方向上的枚举可以省略,因为我们在竖直方向上枚举时,会补充上。。

    另外 我们无需枚举一行中的每一个点,,只需第一个即可,因为,,我们在一个方向上枚举时,,会包含到后面的。

      1 #include <iostream>
      2 #include<cstring>
      3 using namespace std;
      4 struct point{
      5     point *fail;
      6     point *next[26];
      7     bool istail;//是否为单词结尾
      8     int id;//单词的输入顺序
      9     point(){   //初始化
     10         istail =false;
     11         fail = NULL;
     12         memset(next,NULL,sizeof(next));
     13     }
     14 }*q[5000005];//bfs 获得fail 用
     15 
     16 struct pos{
     17     int x,y,dis;
     18 };
     19 pos ans[1005];
     20 point *root = NULL;
     21 int l,c,w;
     22 char map[1005][1005];//puzzle
     23 char str[1005];//模版串
     24 int len[1005];//记录每个摸版的长度
     25 int tail,head;
     26 int dix[8][2] = {-1,0,-1,1,0,1,1,1,1,0,1,-1,0,-1,-1,-1};//顺时针,,上下左右。。。八个方向
     27 char res[9]={"ABCDEFGH"};
     28 void build_trie(char *str,int id){
     29     point *p = root;
     30     int i=0,index;
     31     while(str[i]){
     32         index = str[i]-'A';
     33         if(p->next[index]==NULL) p->next[index] = new point();
     34         p = p->next[index];
     35         i++;
     36     }
     37     p->istail = true;
     38     p->id = id;
     39 }
     40 void get_ac(){
     41     int i;
     42     root->fail = NULL;
     43     q[head++] = root;
     44     while(head!=tail){
     45         point *temp = q[tail++];
     46         point *p =NULL;
     47         for(i=0;i<26;i++){
     48             if(temp->next[i]!=NULL){
     49                 if(temp==root) temp->next[i]->fail=root;
     50                 else{
     51                     p = temp->fail;
     52                     while(p!=NULL){
     53                         if(p->next[i]!=NULL){
     54                             temp->next[i]->fail = p->next[i];
     55                             break;
     56                         }
     57                         p = p->fail;
     58                     }
     59                     if(p==NULL) temp->next[i]->fail = root;
     60                 }
     61                 q[head++] = temp->next[i];
     62             }
     63         }
     64     }
     65 }
     66 
     67 void query(int x,int y,int i){
     68     int index;
     69     point *p,*qq;
     70     p = root;
     71     for(;map[x][y];x+=dix[i][0],y+=dix[i][1]){
     72         index = map[x][y]-'A';
     73         while(p->next[index]==NULL&&p!=root) p = p->fail;
     74         p = p->next[index];
     75         if(p==NULL)
     76             p = root;
     77         qq= p;
     78         while(qq!=root){
     79             if(qq->istail){
     80                 qq->istail = false;
     81                 ans[qq->id].x = x-dix[i][0]*(len[qq->id]-1)-1;//从1开始记得数
     82                 ans[qq->id].y = y-dix[i][1]*(len[qq->id]-1);
     83                 ans[qq->id].dis = i;
     84             }
     85             qq = qq->fail;
     86         }
     87     }
     88 }
     89 int main()
     90 {
     91     root = new point();
     92     cin>>l>>c>>w;
     93     for(int i=1;i<=l;i++)
     94         cin>>map[i];
     95     for(int i=0;i<w;i++){
     96         cin>>str;
     97         len[i] = strlen(str);
     98         build_trie(str,i);
     99     }
    100     head = tail =0;
    101     get_ac();
    102     for(int i=1;i<=l;i++){//枚举水平
    103         query(i,0,1),query(i,0,2),query(i,0,3);//一行只需枚举开头和结尾即可,一列同样
    104         query(i,c-1,5),query(i,c-1,6),query(i,c-1,7);
    105     }
    106     for(int i=0;i<c;i++){//枚举竖直
    107         query(1,i,3),query(1,i,4),query(1,i,5);
    108         query(l,i,7),query(l,i,0),query(l,i,1);
    109     }
    110 
    111     for(int i=0;i<w;i++){
    112         cout<<ans[i].x<<" "<<ans[i].y<<" "<<res[ans[i].dis]<<endl;
    113     }
    114     return 0;
    115 }
  • 相关阅读:
    Windows设置VMware开机自动启动,虚拟机也启动
    PHP中unset,array_splice删除数组中元素的区别
    Linux 出现 E325:ATTENTION swap
    Linux中的info指令
    java创建线程的三种方式——附源码说明
    JVM类加载过程
    java实现责任链模式的小demo
    讲讲java中线程池的实现
    将原型模式和建造者模式结合起来耍一耍
    一个简单的单例模式Demo
  • 原文地址:https://www.cnblogs.com/Bang-cansee/p/3251877.html
Copyright © 2020-2023  润新知