【Trie字典树】ZOJ 3228

来源:互联网 发布:路易斯 汉密尔顿 知乎 编辑:程序博客网 时间:2024/05/23 23:47

这题看了一个解题报告说可以不用自动机做,单用trie树就可以过,于是就做做呗。

思路是这样的:因为每个模式串长度不超过6,所以可以建一棵6层的trie树,从主串的第一个开始枚举长度为6的字串建树,树节点有三个数据域,一个是next数组指向下一个字母,一个是over代表到达当前字母所形成的串可以覆盖的出现次数,notover代表不可以覆盖的次数,last_pos代表当前字母上一次的位置,用于不覆盖情况用的。接着就乱搞,NND,指针竟然爆内存!!!只好改用数组

#include <map>#include <set>#include <list>#include <queue>#include <deque>#include <stack>#include <string>#include <time.h>#include <cstdio>#include <math.h>#include <iomanip>#include <cstdlib>#include <limits.h>#include <string.h>#include <iostream>#include <fstream>#include <algorithm>using namespace std;#define LL long long#define MIN INT_MIN#define MAX INT_MAX#define PI acos(-1.0)#define FRE freopen ("input.txt","r",stdin)#define FF  freopen ("output.txt","w",stdout)#define N 100005char str[N];struct node {    int next[26];    int over;    int notover;    int last_pos;}p[400000];int kk;void init(int pos) {    int i;    for (i = 0 ;i < 26; i++)p[pos].next[i] = -1;    p[pos].last_pos = -1;    p[pos].notover = 0;    p[pos].over = 0;}void Build(char *s,int st) {    int pos = 0;    int i;    for (i = 0; s[i]; i++) {        int id = s[i] - 'a';        if (p[pos].next[id] == -1) {            init(kk);            p[pos].next[id] = kk++;        }   pos = p[pos].next[id];            if (p[pos].last_pos < st) {                p[pos].notover++;                p[pos].last_pos = st+i;            }            p[pos].over++;    }}int gao(int op,char *s) {    int pos = 0;    int i;    int sum = 0;    for (i = 0; s[i]; i++) {        int id = s[i] - 'a';        if (p[pos].next[id] != -1) {            pos = p[pos].next[id];        } else return 0;    }    if (!op) {        sum += p[pos].over;    } else {        sum += p[pos].notover;    }    return sum;}int main () {      char ss[7];    int ca = 1;    while (scanf("%s",str) !=EOF) {        int n;        int i,j;        int len = strlen(str);        init(0);        int cnt;        kk = 1;        for (i = 0; str[i]; i++) {            cnt = 0;            for (j = i; j < i + 6 && j < len; j++) {                ss[cnt++] = str[j];            }            ss[cnt] = '\0';            Build(ss,i);        }        scanf("%d",&n);        printf("Case %d\n",ca++);        while (n--) {            int op;            scanf("%d%s",&op,ss);            printf("%d\n",gao(op,ss));        }        puts("");    }    return 0;}



贴一个指针爆内存版

#include <map>#include <set>#include <list>#include <queue>#include <deque>#include <stack>#include <string>#include <time.h>#include <cstdio>#include <math.h>#include <iomanip>#include <cstdlib>#include <limits.h>#include <string.h>#include <iostream>#include <fstream>#include <algorithm>using namespace std;#define LL long long#define MIN INT_MIN#define MAX INT_MAX#define PI acos(-1.0)#define FRE freopen ("input.txt","r",stdin)#define FF  freopen ("output.txt","w",stdout)#define N 100005char str[N];struct node {    node *next[26];    int over;    int notover;    int last_pos;    node () {        memset(next,NULL,sizeof(next));        over = 0;        notover = 0;        last_pos = -1;    };};void Build(char *s,node *root,int st) {    node *p;    p = root;    int i;    for (i = 0; s[i]; i++) {        int id = s[i] - 'a';        if (p->next[id] == NULL) {            p->next[id] = new node ;        }            if (p->next[id]->last_pos < st) {                p->next[id]->notover++;                p->next[id]->last_pos = st+i;            }            p->next[id]->over++;            p = p->next[id];    }}int gao(int op,char *s,node *root) {    node *p;    p = root;    int i;    int sum = 0;    for (i = 0; s[i]; i++) {        int id = s[i] - 'a';        if (p->next[id]) {            p = p->next[id];        } else return 0;    }    if (!op) {        sum += p->over;    } else {        sum += p->notover;    }    return sum;}int main () {      char ss[7];    int ca = 1;    while (scanf("%s",str) !=EOF) {        int n;        int i,j;        int len = strlen(str);        node *root = new node();        int cnt;        for (i = 0; str[i]; i++) {            cnt = 0;            for (j = i; j < i + 6 && j < len; j++) {                ss[cnt++] = str[j];            }            ss[cnt] = '\0';            Build(ss,root,i);        }        scanf("%d",&n);        printf("Case %d\n",ca++);        while (n--) {            int op;            scanf("%d%s",&op,ss);            printf("%d\n",gao(op,ss,root));        }        puts("");    }    return 0;}

原创粉丝点击