字典树相关习题练习
字典
字典
思路
字典树模板,注意数组大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
   | #include <bits/stdc++.h> using namespace std;
  int tree[2000005][26];      int tot = 1; int Insert(string s) {     int rt = 1;     for(int i = 0; i < s.size(); ++i)     {         int x = s[i] - 'a';         if(!tree[rt][x])         {             tree[rt][x] = ++tot;         }         rt = tree[rt][x];     }     return 1; }
  int Find(string s)       {     int rt = 1;     for(int i = 0; i < s.size(); ++i)     {         int x = s[i] - 'a';         if(!tree[rt][x])  return 0;         rt = tree[rt][x];     }     return 1; } int main() {     int n, m;     cin >> n ;     string s;     for(int i = 1; i <= n; ++i)     {         cin >> s;         Insert(s);     }     cin >> m;     for(int i = 1; i <= m; ++i)     {         cin >> s;         if(Find(s))             cout << "YES" << '\n';         else             cout << "NO" << '\n';     } }
   | 
 
统计难题
HDU - 1251
思路
依然是模板题,注意回车的判断。可以是getline,然后判断字符串长度为0,或者是gets == NULL,但是gets读入的是字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
   | #include <bits/stdc++.h> using namespace std;
  int tree[2000005][26]; int tot = 1; bool is[2100005]; int sum[2100005]; int insert(string s) {     int rt = 1;     for(int i = 0; i < s.size(); ++i)     {         int x = s[i] - 'a';         if(!tree[rt][x])         {             tree[rt][x] = ++tot;         }         sum[tree[rt][x]]++;         rt = tree[rt][x];     }     is[rt] = 1; }
  int find(string s)       {     int rt = 1;     for(int i = 0; i < s.size(); ++i)     {         int x = s[i] - 'a';         if(!tree[rt][x])  return 0;         rt = tree[rt][x];     }     return sum[rt]; } int main() {     string s;     while(getline(cin, s))     {         if(s.size() == 0)             break;         insert(s);     }     while(cin >> s)     {         cout << find(s) << '\n';     } }
   | 
 
Shortest Prefixes
POJ - 2001
题意
要求一个字符串的在能够唯一辨认的前提下的最小前缀。
思路
我们先把所有的单词放在字典树中,然后枚举每个单词,在每个单词中枚举每个字母,如果发现这个前缀的出现的次数等于1,那么就直接输出。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
   | #include <iostream> #include <algorithm> #include <string> #include <cstring> #include <sstream> #include <map> #include <vector> #include <stdio.h> using namespace std; int tot = 1; int tree[20005][26]; bool vis[20005]; int sum[20005]; int insert(string s) {     int rt = 1;     for(int i = 0; i < s.size(); ++i)     {         int x = s[i] - 'a';         if(!tree[rt][x])             tree[rt][x] = ++tot;         sum[tree[rt][x]]++;         rt = tree[rt][x];     } }
  int find(string s) {     int rt = 1;     for(int i = 0; i < s.size(); ++i)     {         int x = s[i] - 'a';         if(!tree[rt][x])             return 0;         rt = tree[rt][x];     }     return sum[rt]; } int main() {     string s;     vector<string>V;     while(cin >> s)     {         insert(s);         V.push_back(s);     }     for(int i = 0; i < V.size(); ++i)     {         string s1;         int flag = 0;         for(int j = 0; j < V[i].size(); ++j)         {             s1 += V[i][j];             int num = find(s1);             if(num == 1)             {                 flag = 1;                 cout << V[i] << ' ' << s1 << '\n';                 break;             }         }         if(!flag)         {             cout << V[i] << ' ' << s1 << '\n';         }     }
  }
   |