几道字典树题目

来源:互联网 发布:淘宝网上如何买飞机票 编辑:程序博客网 时间:2024/05/02 01:31


POJ 2418 Hardwood Species

题意:给一些字符串,按照字典序输出他们,并且输出频率...........


#include <iostream>#include <algorithm>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <string>#include <vector>#include <set>#include <queue>#include <stack>#include <climits>//形如INT_MAX一类的#define MAX 100005#define INF 0x7FFFFFFF#define REP(i,s,t) for(int i=(s);i<=(t);++i)#define ll long long#define mem(a,b) memset(a,b,sizeof(a))#define mp(a,b) make_pair(a,b)#define L(x) x<<1#define R(x) x<<1|1# define eps 1e-5//#pragma comment(linker, "/STACK:36777216") ///传说中的外挂using namespace std;struct Trie {    int next[128];    int sum;    char s[33];    void init() {        memset(next,0,sizeof(next));        sum = 0;    }} a[301111];int num,cnt,root;char str[33];void insert(char *key) {    int p = root;    for(int i=0; key[i]; i++) {        int t = int(key[i]);        if(a[p].next[t] == 0) {            a[p].next[t] = ++ num;            a[num].init();        }        p = a[p].next[t];    }    a[p].sum ++;    a[p].s[0] = '\0';    strcpy(a[p].s,key);}void dfs(int p) {    if(a[p].sum != 0) {        printf("%s ",a[p].s);        printf("%.4f\n",(a[p].sum * 1.0) / cnt * 100);    }    for(int i=0; i<128; i++) {        if(a[p].next[i] != 0) {            int t = a[p].next[i];            dfs(t);        }    }}int main() {    root = 0; num = 0; cnt = 0;    a[root].init();    while(gets(str)) {        int len = strlen(str);        if(len == 0) break;        cnt ++;        insert(str);    }    dfs(0);    return 0;}



HDU 2846 Repository

题意:给定一些单词作为字典,和一些单词作为询问,对于每个询问,求出它在所有字典单词中作为单词子串出现的次数(它只能在同一单词中以子串形式出现一次)

对于每个字典中的单词,让它所有后缀都在字典树中建树,这样只要在字典树中找前缀就等同于找到子串了

需要注意的是,它只能在同一单词中以子串形式出现一次,如:str:dddddd       则ddd在str中只出现一次,所以对于同一单词产生的后缀,需要判重......


#include <iostream>#include <algorithm>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <string>#include <vector>#include <set>#include <queue>#include <stack>#include <climits>//形如INT_MAX一类的#define MAX 100005#define INF 0x7FFFFFFF#define REP(i,s,t) for(int i=(s);i<=(t);++i)#define ll long long#define mem(a,b) memset(a,b,sizeof(a))#define mp(a,b) make_pair(a,b)#define L(x) x<<1#define R(x) x<<1|1# define eps 1e-5//#pragma comment(linker, "/STACK:36777216") ///传说中的外挂using namespace std;int n,q,root,cnt;char str[22];char keyword[22];struct Trie {    int next[26];    int num;    int kind;    void init() {        memset(next,0,sizeof(next));        num = 0;        kind = -1;    }} a[1111111];void insert(char *key,int id,int kind) {    int p = root;    for(int i=id; key[i]; i++) {        int t = key[i] - 'a';        if(a[p].next[t] == 0) {            a[p].next[t] = ++cnt;            a[cnt].init();        }        p = a[p].next[t];        if(a[p].kind != kind) {            a[p].kind = kind;            a[p].num ++;        }    }}int query(char *key) {    int p = root;    int sum = 0;    for(int i=0; key[i]; i++) {        int t = key[i] - 'a';        if(a[p].next[t] == 0) return 0;        p = a[p].next[t];    }    sum += a[p].num;    return sum;}int main() {    root = 0;    cnt = 0;    scanf("%d",&n);    for(int i=0; i<n; i++) {        scanf("%s",str);        int len = strlen(str);        for(int j=0; j<len; j++)            insert(str,j,i);    }    scanf("%d",&q);    for(int i=0; i<q; i++) {        scanf("%s",keyword);        printf("%d\n",query(keyword));    }    return 0;}

POJ 1204 Word Puzzles

题意:给定了一个1000 * 1000 的由大写字母组成的矩阵,现在给出一些单词,要求在矩阵中找到每个单词,记录首字母的位置,以及它沿着什么方向走(8个方向,米字型)


将单词建立字典树,然后在矩阵中枚举每个点作为起点,8个方向直接找就行了..........

#include <iostream>#include <algorithm>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <string>#include <vector>#include <set>#include <queue>#include <stack>#include <climits>//形如INT_MAX一类的#define MAX 100005#define INF 0x7FFFFFFF#define REP(i,s,t) for(int i=(s);i<=(t);++i)#define ll long long#define mem(a,b) memset(a,b,sizeof(a))#define mp(a,b) make_pair(a,b)#define L(x) x<<1#define R(x) x<<1|1# define eps 1e-5//#pragma comment(linker, "/STACK:36777216") ///传说中的外挂using namespace std;int n,m,w;struct Word {    int x,y,dir,kind;    char word[1111];}s[1111];char str[1111][1111];int dx[] = {-1,-1,0,1,1,1,0,-1};int dy[] = {0,1,1,1,0,-1,-1,-1};int root , cnt ;struct Trie {    int next[26];    int kind;    void init() {        memset(next,0,sizeof(next));        kind = -1;    }}a[1111111];void insert(char *key, int kind) {    int p = root;    for(int i=0; key[i]; i++) {        int t = key[i] - 'A';        if(a[p].next[t] == 0) {            a[p].next[t] = ++ cnt;            a[cnt].init();        }        p = a[p].next[t];    }    a[p].kind = kind;}void solve() {    for(int i=0; i<n; i++) {        for(int j=0; j<m; j++) {            int t = str[i][j] - 'A';            if(a[root].next[t] == 0) continue;            for(int k=0; k<8; k++) {                int p = a[root].next[t];                int x = i, y = j;                while(x >= 0 && x < n && y >= 0 && y < m && p) {                    if(a[p].kind != -1) {                        s[a[p].kind].dir = k;                        s[a[p].kind].x = i;                        s[a[p].kind].y = j;                    }                    x = x + dx[k];                    y = y + dy[k];                    int t = str[x][y] - 'A';                    p = a[p].next[t];                }            }        }    }    for(int i=0; i<w; i++) {        printf("%d %d %c\n",s[i].x,s[i].y,s[i].dir + 'A');    }}int main() {    while(scanf("%d%d%d",&n,&m,&w) != EOF) {        root = 0; cnt = 0;        for(int i=0; i<n; i++) scanf("%s",str[i]);        for(int i=0; i<w; i++) {            scanf("%s",s[i].word);            s[i].kind = i;            insert(s[i].word,i);        }        solve();    }    return 0;}


待续.....


原创粉丝点击