计蒜客---糟糕的Bug(Trie树)

蒜头君作为蒜厂的工程师,在开发网站时不小心写出了一个 Bug:当用户输入密码时,如果既和自己的密码一致,也同时是另一个用户密码的 前缀 时,用户会跳转到 404 页。

然而蒜头君坚称:我们的用户那么少,怎么可能触发这个 Bug……

机智的你,能不能帮蒜头君确认一下这个 Bug 到底会不会触发呢?

样例输入

第一行输入一个整数 n(1 \leq n \leq 233333)n(1n233333),表示蒜厂网站的用户数。接下来一共 nn 行,每行一个由小写字母a-z组成的字符串,长度不超过 1010,表示每个用户的密码。蒜厂的数据库容量太小,所有密码长度加起来小于 466666466666。

样例输出

如果触发了 Bug 则输出一行Bug!,否则输出一行Good Luck!

样例输入1

3
abc
abcdef
cdef

样例输出1

Bug!

样例输入2

3
abc
bcd
cde

样例输出2

Good Luck!

 

思路:可以建个数组枚举,效率太低。可以运用trie树(字典树)。关键在于题目中加重的前缀两字,怎么判断。。

详细代码:

#include<iostream>

#include<cstring>

 

using namespace std;

const int maxn=500000;

const int maxc=26;

 

int *ch[maxn],tol,cnt[maxn];

void init(){

       tol=0;

       memset(ch,0,sizeof(ch));

       memset(cnt,0,sizeof(cnt));

    }

bool insert(char *str,int size){

       int p=0,x=0;

       for(int i=0;str[i];i++){

           if(ch[p]==NULL){

                ch[p]= new int[maxc];

               memset(ch[p],-1,sizeof(int)*maxc);

           }if(ch[p][str[i]-‘a’]==-1){

                ch[p][str[i]-‘a’]=++tol;

           }else x++;

           p=ch[p][str[i]-‘a’];

           //cout<<a1<<” “<<i+1<<endl;

           if(cnt[p]||(x==size))return false;  //判断前缀的关键语句

       }

      cnt[p]++;

   //cout<<x;

   return true;

    }

int main(){

   int n;

   init();

   cin>>n;

   for(int i=0;i<n;i++){

       char s[15];

       cin>>s;

       //cout<<strlen(s)<<endl;

       if(!insert(s,strlen(s))){

           cout<<“Bug!\n”;

           return 0;

       }

    }

   cout<<“Good Luck!\n”;

}

    原文作者:Trie树
    原文地址: https://blog.csdn.net/wzgcrc/article/details/78826958
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞