首页 > 代码库 > HDOJ1251解题报告

HDOJ1251解题报告

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1251

题目概述:

  给你一些单词和一些询问,对于每个询问求出所有单词中以询问为前缀的单词个数。

大致思路:

  稍微修改一下Tire树就好了,对每个节点增加一个标记来记录到这个节点共有几个单词,这个题还需要注意用g++提交指针版的会MLE,所以需要用数组形式的Tire树。

  年轻的我还是被输入给坑了……果然naive.

复杂度分析:

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <ctime>
 7 #include <map>
 8 #include <queue>
 9 #include <cstring>
10 #include <algorithm>
11 using namespace std;
12 
13 #define sacnf scanf
14 #define maxn 1000010
15 #define inf 1061109567
16 #define Eps 0.001
17 #define PI 3.1415927
18 #define mod 9973
19 #define MAXNUM 10000
20 void Swap(int &a,int &b) {int t=a;a=b;b=t;}
21 int Abs(int x) {return (x<0)?-x:x;}
22 typedef long long ll;
23 
24 int tree[maxn][26];
25 int cnt[maxn];
26 int dir=1;
27 
28 void Insert(char *s)
29 {
30     int p=0,len=strlen(s);
31     for(int i=0;i<len;i++)
32     {
33         if(!tree[p][s[i]-a])
34         {
35             tree[p][s[i]-a]=dir;
36             cnt[dir]++;dir++;
37         }
38         else cnt[tree[p][s[i]-a]]++;
39         p=tree[p][s[i]-a];
40     }
41 }
42 
43 int query(char *s)
44 {
45     int p=0,len=strlen(s);
46     for(int i=0;i<len;i++)
47     {
48         if(tree[p][s[i]-a]!=0) p=tree[p][s[i]-a];
49         else return 0;
50     }
51     return cnt[p];
52 }
53 
54 int main()
55 {
56     //freopen("data.in","r",stdin);
57     //freopen("data.out","w",stdout);
58     //clock_t st=clock();
59     char s[20];
60     memset(cnt,0,sizeof(cnt));
61     while(gets(s))
62     {
63         if(strlen(s)==0) break;
64         Insert(s);
65     }
66     while(gets(s))
67     {
68         printf("%d\n",query(s));
69     }
70     //clock_t ed=clock();
71     //printf("\n\nTime Used : %.5lf Ms.\n",(double)(ed-st)/CLOCKS_PER_SEC);
72     return 0;
73 }

 

HDOJ1251解题报告