Quantcast
Channel: CSDN博客推荐文章
Viewing all articles
Browse latest Browse all 35570

POJ 1204 Trie树

$
0
0

题意:这道题还是蛮有意思的,首先,他给出一个n * m 的表格,里面都是大写字母,然后再给出k个串,问这个k个串在表格的什么位置,输出起始坐标和每个串在表格中的方向,一共8个方向。

思路:一开始就想,对表格的八个方向都建一个AC自动机,然后拿k个串一个一个匹配,但是发现代码复杂度极高,非常不好实现。

那可以从串的角度考虑,我们对这些串建一个TRIE树,那么每次枚举表格的起点,然后从这个起点出发,沿着八个方向搜一遍,看是否有匹配上的前缀,直接记录即可。

但是,需要注意的一点是,每次搜到一个前缀的时候,切记不可直接return .

我们考虑这样的两个串

abcd

abcde

对于串2,要搜到他显然得先搜到串1,所以搜到串1的时候不能return ,否则就搜不到串2了,具体见代码。

#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
#define Max 2505
#define FI first
#define SE second
#define ll long long
#define PI acos(-1.0)
#define inf 0x3fffffff
#define LL(x) ( x << 1 )
#define bug puts("here")
#define PII pair<int,int>
#define RR(x) ( x << 1 | 1 )
#define mp(a,b) make_pair(a,b)
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i )

using namespace std;

inline void RD(int &ret) {
    char c;
    int flag = 1 ;
    do {
        c = getchar();
        if(c == '-')flag = -1 ;
    } while(c < '0' || c > '9') ;
    ret = c - '0';
    while((c=getchar()) >= '0' && c <= '9')
        ret = ret * 10 + ( c - '0' );
    ret *= flag ;
}

inline void OT(int a) {
    if(a >= 10)OT(a / 10) ;
    putchar(a % 10 + '0') ;
}

inline void RD(double &ret) {
    char c ;
    int flag = 1 ;
    do {
        c = getchar() ;
        if(c == '-')flag = -1 ;
    } while(c < '0' || c > '9') ;
    ll n1 = c - '0' ;
    while((c = getchar()) >= '0' && c <= '9') {
        n1 = n1 * 10 + c - '0' ;
    }
    ll n2 = 1 ;
    while((c = getchar()) >= '0' && c <= '9') {
        n1 = n1 * 10 + c - '0' ;
        n2 *= 10 ;
    }
    ret = flag * (double)n1 / (double)(n2) ;
}
/*********************************************/

#define N 1111111
int n , m ;
struct TT {
    int next[26] ;
    int count ;
    void init() {
        mem(next , 0) ;
        count = 0 ;
    }
} T[N] ;
int num = 0 ;
char Map[1111][1111] ;
void init() {
    num = 0 ;
    T[0].init() ;
}
void insert(char *a ,int id) {
    int l = strlen(a) ;
    int now = 0 ;
    for (int i = 0 ; i < l ; i ++ ) {
        int k = a[i] - 'A' ;
        if(T[now].next[k] == 0) {
            T[now].next[k] = ++ num ;
            T[num].init() ;
        }
        now = T[now].next[k] ;
    }
    T[now].count = id ;
}
int fkk = 0 ;
int mx[8] = {-1 , -1 , 0 , 1 , 1 , 1 , 0  , -1} ;
int my[8] = { 0 ,  1 , 1 , 1 , 0 , -1 ,-1 , -1} ;
struct ANS {
    int s , e ;
    char fk ;
} ans[N] ;
int s , e ;
int inmap(int x ,int y) {
    if(x >= 0 && x < n && y >= 0 && y < m)return 1 ;
    return 0 ;
}
void fk(int x , int y ,int dir) {
    if(fkk == 0)return ;
    if(!inmap(x , y))return ;
    if(T[fkk].count) {
        ans[T[fkk].count].s = s ;
        ans[T[fkk].count].e = e ;
        ans[T[fkk].count].fk = char(dir + 'A') ;
//        T[fkk].count = 0 ;//这里加不加都可以,反正是spj,加了速度快一点
//        return ; //切记不要return
    }
    int next = Map[x + mx[dir]][y + my[dir]] - 'A' ;
    fkk = T[fkk].next[next] ;
    if(inmap(x + mx[dir] , y + my[dir]))
        fk(x + mx[dir] , y + my[dir] , dir) ;
}
char fk1[1111] ;
int main() {
    int xx ;
    while(cin >> n >> m >> xx ) {
        init() ;
        for (int i = 0 ; i < n ; i ++ )scanf("%s",Map[i]) ;
        for (int i = 1 ; i <= xx ; i ++ ) {
            scanf("%s",fk1) ;
            insert(fk1 , i) ;
        }
        for (int i = 0 ; i < n ; i ++ ) {
            for (int j = 0 ; j < m ; j ++ ) {
                for (int k = 0 ; k < 8 ; k ++ ) {
                    s = i ;
                    e = j ;
                    fkk = T[0].next[Map[i][j] - 'A'] ;
                    if(!fkk)break ;
                    fk(i , j , k) ;
                }
            }
        }
        for (int i = 1 ; i <= xx ; i ++ ) {
            printf("%d %d ",ans[i].s , ans[i].e) ;
            putchar(ans[i].fk) ;putchar('\n') ;
        }
    }
    return 0 ;
}


作者:kdqzzxxcc 发表于2013-8-30 19:05:01 原文链接
阅读:49 评论:0 查看评论

Viewing all articles
Browse latest Browse all 35570

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>