zoukankan      html  css  js  c++  java
  • [CodingHarder] Trie树

    https://vjudge.net/contest/311647#overview

    A - Shortest Prefixes

    给定n个串,求出每个串的“唯一最短前缀”

    用bo[i]表示从字典树根节点0到节点i连成的字符串为前缀的单词个数,那么在查询一个单词的时候,在该路径的某个节点i出现了bo[i]=1的情况,就说明这个字符串是该单词的唯一前缀。

     1 #include<iostream>
     2 #include<sstream>
     3 #include<fstream>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<iomanip>
     7 #include<cstdlib>
     8 #include<cctype>
     9 #include<vector>
    10 #include<string>
    11 #include<cmath>
    12 #include<ctime>
    13 #include<stack>
    14 #include<queue>
    15 #include<map>
    16 #include<set>
    17 #define mem(a,b) memset(a,b,sizeof(a))
    18 #define random(a,b) (rand()%(b-a+1)+a)
    19 #define ll long long
    20 #define ull unsigned long long
    21 #define e 2.71828182
    22 #define Pi acos(-1.0)
    23 #define ls(rt) (rt<<1)
    24 #define rs(rt) (rt<<1|1)
    25 #define lowbit(x) (x&(-x))
    26 using namespace std;
    27 const int MAXN=2e4+5;
    28 const int Z=26;
    29 int ch[MAXN][Z];
    30 int bo[MAXN];
    31 char str[1001][21];
    32 int tot=1;
    33 void insert(char *s)
    34 {
    35     int l=strlen(s),u=1;
    36     for(int i=0;i<l;++i)
    37     {    
    38         int c=s[i]-'a';
    39         if(!ch[u][c]) ch[u][c]=++tot;
    40         u=ch[u][c];
    41         bo[u]++;
    42     }
    43 }
    44 void query(char *s)
    45 {
    46     int l=strlen(s),u=1;
    47     for(int i=0;i<l;++i)
    48     {
    49         int c=s[i]-'a';
    50         if(bo[u]==1) break;
    51         putchar(s[i]);
    52         u=ch[u][c];
    53     }
    54     putchar('
    ');
    55 }
    56 int main()
    57 {
    58     int cnt=0;
    59     while(scanf("%s",str[++cnt])!=EOF)
    60     insert(str[cnt]);
    61     
    62     for(int i=1;i<=cnt;++i)
    63     {
    64         cout<<str[i]<<' ';
    65         query(str[i]);
    66     }
    67 }
    View Code

    B - Wild Words

     模糊匹配,一个'?'字符匹配任意一个字符,一个'*'字符匹配0个、1个或多个字符。

    dfs和Trie的结合

    两个指针在查询的字符串和Trie上走

      1 #include<iostream>
      2 #include<sstream>
      3 #include<fstream>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<iomanip>
      7 #include<cstdlib>
      8 #include<cctype>
      9 #include<vector>
     10 #include<string>
     11 #include<cmath>
     12 #include<ctime>
     13 #include<stack>
     14 #include<queue>
     15 #include<map>
     16 #include<set>
     17 #define mem(a,b) memset(a,b,sizeof(a))
     18 #define random(a,b) (rand()%(b-a+1)+a)
     19 #define ll long long
     20 #define ull unsigned long long
     21 #define e 2.71828182
     22 #define Pi acos(-1.0)
     23 #define ls(rt) (rt<<1)
     24 #define rs(rt) (rt<<1|1)
     25 #define lowbit(x) (x&(-x))
     26 using namespace std;
     27 const int MAXN=6e5+5;
     28 //const int MAXN=1e5+5;
     29 const int Z=28;
     30 int ch[MAXN][Z];
     31 vector<int> bo[MAXN];
     32 vector<int> ans;
     33 char str[30];
     34 bool isok[MAXN];
     35 bool visit[MAXN];
     36 int n,m,len;
     37 int tot=1;
     38 int read()
     39 {
     40     int s=1,x=0;
     41     char ch=getchar();
     42     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
     43     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
     44     return x*s;
     45 }
     46 int f(char c)
     47 {
     48     if(c=='?') return 26;
     49     if(c=='*') return 27;
     50     return c-'a';
     51 }
     52 void insert(char *s,int id)
     53 {
     54     int l=strlen(s),u=1;
     55     for(int i=0;i<l;++i)
     56     {
     57         if(!ch[u][f(s[i])]) ch[u][f(s[i])]=++tot;
     58         u=ch[u][f(s[i])];
     59         if(f(s[i])==27) isok[u]=true;
     60     }
     61     bo[u].push_back(id);
     62 }
     63 void find(int le,int u)
     64 {
     65     if(le==len)
     66     {
     67         int sz=bo[u].size();
     68         for(int i=0;i<sz;++i)
     69         if(!visit[bo[u][i]]) 
     70         {
     71             visit[bo[u][i]]=true;
     72             ans.push_back(bo[u][i]);
     73         }
     74         if(ch[u][27]) find(le,ch[u][27]);
     75         return;
     76     }
     77     int c=f(str[le]);
     78     if(ch[u][c]) find(le+1,ch[u][c]);//精准匹配 
     79     if(ch[u][26]) find(le+1,ch[u][26]);//?字符匹配 
     80     if(ch[u][27])//*字符匹配 
     81     {
     82         find(le+1,ch[u][27]);//匹配1个 
     83         find(le,ch[u][27]);//匹配0个 
     84     }
     85     if(isok[u]) find(le+1,u);//*匹配多个 
     86 }
     87 int main()
     88 {
     89     ios::sync_with_stdio(false);
     90     cin.tie(0);cout.tie(0);
     91     cin>>n>>m;
     92     for(int i=1;i<=n;++i)
     93     {
     94         cin>>str;
     95         insert(str,i-1);
     96     }
     97     for(int i=1;i<=m;++i)
     98     {
     99         cin>>str;
    100         len=strlen(str);
    101         ans.clear();
    102         mem(visit,0);
    103         find(0,1);
    104         int sz=ans.size();
    105         if(!sz)
    106         {
    107             cout<<"Not match"<<endl;
    108             continue;
    109         }
    110         sort(ans.begin(),ans.end());
    111         for(int j=0;j<sz;++j)
    112         {
    113             if(j==sz-1) cout<<ans[j]<<endl;
    114             else cout<<ans[j]<<' ';
    115         }
    116     }
    117     return 0;
    118 }
    View Code

    C - Phone List

    给定n个长度不超过10的数字串,问其中是否存在两个数字串S、T,使得S是T的前缀。
    将所有的字符串构成一棵Trie,在构建过程中可以顺便判断答案。
    若当前串插入后没有新建任何结点,则当前串肯定是之前插入的某个串的前缀;
    若插入过程中,有某个经过的结点带有串结尾标记,则之前插入的某个串是当前串的前缀 
     1 #include<iostream>
     2 #include<sstream>
     3 #include<fstream>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<iomanip>
     7 #include<cstdlib>
     8 #include<cctype>
     9 #include<vector>
    10 #include<string>
    11 #include<cmath>
    12 #include<ctime>
    13 #include<stack>
    14 #include<queue>
    15 #include<map>
    16 #include<set>
    17 #define mem(a,b) memset(a,b,sizeof(a))
    18 #define random(a,b) (rand()%(b-a+1)+a)
    19 #define ll long long
    20 #define ull unsigned long long
    21 #define e 2.71828182
    22 #define Pi acos(-1.0)
    23 #define ls(rt) (rt<<1)
    24 #define rs(rt) (rt<<1|1)
    25 #define lowbit(x) (x&(-x))
    26 using namespace std;
    27 const int MAXN=2e5+5;
    28 const int Z=10;
    29 int ch[MAXN][Z];
    30 int tot=1;
    31 bool bo[MAXN];
    32 bool insert(char *s)
    33 {
    34     int l=strlen(s),u=1;
    35     bool flag=false;
    36     for(int i=0;i<l;++i)
    37     {
    38         int c=s[i]-'0';
    39         if(!ch[u][c]) ch[u][c]=++tot;
    40         else if(i==l-1) flag=true;
    41         u=ch[u][c];
    42         if(bo[u]) flag=true;
    43      }
    44      bo[u]=true;
    45      return flag;
    46 }
    47 int read()
    48 {
    49     int s=1,x=0;
    50     char ch=getchar();
    51     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
    52     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
    53     return x*s;
    54 }
    55 int main()
    56 {
    57     ios::sync_with_stdio(false);
    58     cin.tie(0);cout.tie(0);
    59     int test;cin>>test;
    60     while(test--)
    61     {
    62         int n;cin>>n;
    63         bool flag=false;
    64         mem(ch,0);mem(bo,0);
    65         tot=1;
    66         char str[20];
    67         for(int i=1;i<=n;++i)
    68         {
    69             cin>>str;
    70             if(insert(str)) flag=true;
    71         }
    72         if(flag) cout<<"NO"<<endl;
    73         else cout<<"YES"<<endl;
    74     }
    75 }
    View Code
  • 相关阅读:
    Android 媒体存储服务(二)
    Android 媒体存储服务(一)
    MTP in Android详解
    Source Insight 常用设置和快捷键大全
    Android 中onSaveInstanceState和onRestoreInstanceState学习
    Android RadioButton 语言无法切换问题
    Android 中onConfigurationChanged问题
    欢迎访问我的CSDN博客
    Java-异常
    Java-finally相关问题
  • 原文地址:https://www.cnblogs.com/wangzhebufangqi/p/11527683.html
Copyright © 2011-2022 走看看