题目来源:计蒜客https://www.jisuanke.com/minicourse/812/42071
蒜头君作为蒜厂的工程师,在开发网站时不小心写出了一个 Bug:当用户输入密码时,如果既和自己的密码一致,也同时是另一个用户密码的 前缀 时,用户会跳转到 404 页。
然而蒜头君坚称:我们的用户那么少,怎么可能触发这个 Bug……
机智的你,能不能帮蒜头君确认一下这个 Bug 到底会不会触发呢?
样例输入
第一行输入一个整数n(1≤n≤233333),表示蒜厂网站的用户数。接下来一共 n 行,每行一个由小写字母a-z
组成的字符串,长度不超过 10,表示每个用户的密码。蒜厂的数据库容量太小,所有密码长度加起来小于 466666。
样例输出
如果触发了 Bug 则输出一行Bug!
,否则输出一行Good Luck!
。
样例输入1
3 abc abcdef cdef
样例输出1
Bug!
样例输入2
3 abc bcd cde
样例输出2
Good Luck!
题目类型就是串匹配,找前缀,多串情况下,很应该想到前缀树,也称为Trie树。
我们要注意的地方是 本身Find函数查找密码本身过程中一定会返回1 我们要手动返回0
第二 因为一定能找到 所以在find函数中 我手动注释了两个if 因为不会除法(这题的小细节
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAX_N = 466670;
const int MAX_C = 26;
char s[233335][15];
struct Trie{
int *ch[MAX_N];
int tot;
int cnt[MAX_N];
void init(){
tot = 0;
memset(cnt,0,sizeof(cnt));
memset(ch,0,sizeof(ch));
}
void Insert(char *str){
int p = 0;
for(int i=0;str[i];++i){
if(ch[p]==NULL){
ch[p] = new int[MAX_C];
memset(ch[p],-1,sizeof(int) * MAX_C);
}
if(ch[p][str[i]-'a']==-1){
ch[p][str[i]-'a']=++tot;
}
p = ch[p][str[i]-'a'];
}
cnt[p]++;
}
int Find(char *str){
int p = 0;
for(int i = 0;str[i];++i){
if(cnt[p]!= 0 && str[i]) return 1;
//if(ch[p]==NULL) return 0;
//if(ch[p][str[i]-'a']==-1) return 0;
p = ch[p][str[i]-'a'];
}
return 0;
}
};
Trie trie;
int main(){
int t;
scanf("%d",&t);
//sgetchar();
bool ans = false;
for(int i =0;i<t;++i){
scanf("%s",s[i]);
trie.Insert(s[i]);
}
for ( int i = 0 ; i < t ; ++ i ) {
if ( trie.Find(s[i]) ) {
ans = true;
}
}
if ( ans ) {
puts("Bug!");
} else {
puts("Good Luck!");
}
return 0;
}