码迷,mamicode.com
首页 > 其他好文 > 详细

字典树专题

时间:2016-04-25 00:37:05      阅读:295      评论:0      收藏:0      [点我收藏+]

标签:

一、模板

数组版的:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define maxn 500050
 4 char str[50010][100];
 5 int nxt;
 6 struct node
 7 {
 8     int val;
 9     int next[26];
10 }tree[maxn];
11 //将结构体改成数组更容易初始化,treenext[maxn][26],treeval[maxn] 
12 int add()
13 {
14     memset(&tree[nxt],0,sizeof(node));
15     return nxt++;
16 }
17 void insert(char *s)
18 {
19     int rt=0,len=strlen(s);
20     for(int i=0;i<len;i++)
21     {
22         int c=s[i]-a;
23         if(!tree[rt].next[c])
24         {
25             tree[rt].next[c]=add();
26         }
27         rt=tree[rt].next[c];
28     }
29     tree[rt].val++;
30 }
31 int query(char *s){
32     int rt=0, len = strlen(s);
33     int id=-1;
34     for(int i=0; i<len; i++){
35         int c=s[i]-0;
36         if(!tree[rt].next[c]) return -1;
37         rt=tree[rt].next[c];
38         id = tree[rt].val;
39     }
40     return id;
41 }
42 int main()
43 {
44     int l=0;
45     nxt=1;
46     while(scanf("%s",str[l])!=EOF)
47     {
48         insert(str[l]);
49         l++;
50     }
51     for(int i=0;i<l;i++)
52     {
53         printf("%d\n",query(str[i]));
54     }
55     return 0;
56 }

 指针版的:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 char c[100][100];
 5 const int MAX=10;
 6 typedef struct Node
 7 {
 8     int val;
 9     struct Node *next[MAX];
10 }TrieNode;
11 
12 TrieNode *head;
13 
14 void insert(char str[], int id)
15 {
16     Node *t,*s=head;
17     int len=strlen(str);
18     for(int i=0;i<len;i++)
19     {
20         int c=str[i]-0;
21         if(s->next[c]==NULL)
22         {
23             t=new Node;
24             for(int j=0;j<10;j++) t->next[j]=NULL;
25             t->val=-1;
26             s->next[c]=t;
27         }
28         s=s->next[c];
29         if(s->val<0) s->val=id;
30     }
31 }
32 
33 int query(char str[])
34 {
35     Node *s=head;
36     int ans;
37     int len=strlen(str);
38     for(int i=0;i<len;i++)
39     {
40         int c=str[i]-0;
41         if(s->next[c]==NULL) return -1;
42         s=s->next[c];
43         ans=s->val;
44     }
45     return ans;
46 }
47 
48 void Tree_Del(Node *p)
49 {
50     for(int i=0;i<10;i++)
51     {
52         if(p->next[i]!=NULL)
53           Tree_Del(p->next[i]);
54     }
55     free(p);
56 }
57 
58 int main()
59 {
60     head=new Node;
61     for(int i=0;i<10;i++)head->next[i]=NULL;
62     head->val=-1;
63     int n, m;
64     char str[60];
65     scanf("%d%d",&n, &m);
66     for(int i=0; i<n; i++)
67     {
68         scanf("%s",str);
69         insert(str, i);
70     }
71     for(int i=0; i<m; i++){
72         scanf("%s", str);
73         printf("%d\n", query(str));//输出字符串是在第几次出现过 
74     }
75     Tree_Del(head);//释放空间,防止超内存 
76     return 0;
77 }

 

二、题目

1、【HDU 4099Revenge of Fibonacci

题意:给出斐波那契数列的前k位,k不超过40,找出最小的正整数n,满足F(n)的前k位与给定数的前k位相同,斐波那契数列的项数不超过100000

解题思路:本题可以分为两步:

第一步就是预处理出100000项斐波那契数列的前40位,插入到字典树中。

第二步就是查询匹配求最小的n

对于第一步,我们可以把斐波那契数列精确到50多位,然后只存40位即可,这样就防止进位的误差。在斐波那契数列加法过程中,我们只把它的前50多位进行相加,不然存不下。

技术分享
 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <string>
 6 using namespace std;
 7 const int N=1e6+10;
 8 char f[5][100], str[100];
 9 void add(char *a, char *b, char *c){
10     int lena=strlen(a), lenb=strlen(b);
11     int lenc=0, tmp=0;
12     while(1){
13         if(lena==0 && lenb==0) break;
14         if(lena==0){
15             int sum=b[--lenb]-0+tmp;
16             c[lenc++] = sum%10+0;
17             tmp = sum/10;
18         }
19         else{
20             int sum=b[--lenb]-0+a[--lena]-0+tmp;
21             c[lenc++] = sum%10+0;
22             tmp = sum/10;
23         }
24     }
25     if(tmp) c[lenc++]=tmp+0;
26     strcpy(a, b);
27     for(int j=0; j<lenc; j++){
28         b[j] = c[lenc-j-1];
29     }
30     b[lenc]=\0;
31 }
32 int nxt;
33 struct node{
34     int val, next[10];
35 }tree[7*N];
36 int add()
37 {
38     memset(&tree[nxt],0,sizeof(node));
39     return nxt++;
40 }
41 
42 void insert(char *s, int id)
43 {
44     int rt=0,len=strlen(s);
45     for(int i=0;i<min(len, 41);i++)
46     {
47         int c=s[i]-0;
48         if(!tree[rt].next[c])
49         {
50             tree[rt].next[c]=add();
51             tree[tree[rt].next[c]].val=id;
52         }
53         rt=tree[rt].next[c];
54     }
55 }
56 
57 int query(char *s){
58     int rt=0, len = strlen(s);
59     int id=-1;
60     for(int i=0; i<len; i++){
61         int c=s[i]-0;
62         if(!tree[rt].next[c]) return -1;
63         rt=tree[rt].next[c];
64         id = tree[rt].val;
65     }
66     return id;
67 }
68 int main(){
69     nxt = 1;
70     f[0][0]=1, f[1][0]=1;
71     insert(f[0], 0);
72     for(int i=2; i<100000; i++){
73         int len=strlen(f[0]), llen=strlen(f[1]);
74         if(llen>60){
75             f[1][llen-1]=\0;
76             f[0][len-1]=\0;
77         }
78         add(f[0], f[1], f[3]);
79         insert(f[1], i);
80     }
81     int t, cas=1;
82     scanf("%d", &t);
83     while(t--){
84         scanf("%s", str);
85         int flag = query(str);
86         printf("Case #%d: %d\n", cas++, flag);
87     }
88     return 0;
89 }
View Code

 

字典树专题

标签:

原文地址:http://www.cnblogs.com/yscc/p/5428765.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!