一本通 电话列表
ACwing161
solution
假设已经插入了 \(i\) 个字符串,现在要插入一个字符串 \(str\) 那么此时 \(str\) 产生不兼容的方式只有两种
- \(str\) 是前 \(i\) 个已插入字符串的前缀
- 前 \(i\) 个字符串中存在 \(str\) 的前缀
对于第一种情况, \(str\) 这个字符串在 \(trie\) 中一定已经存在,所以一定不需要新开节点。也就是在插入这个字符串之后 \(tot\) 的大小一定不会改变。
对于第二种情况, 在插入 \(str\) 时一定会遇到一个节点被标记为了终点
综合上面两种判断方法,我们就可以在插入的过程中判断该电话列表是否兼容
code
#include <bits/stdc++.h>
using namespace std ;
const int maxn = 1e5 + 7 ;
int t , n , tot ;
bool pd ;
char s[maxn] ;
int tire[maxn][10] ;
bool End[maxn] ;
bool insert(char* s)
{
int len = strlen(s ) , p = 0 , cnt = 0, Pd = true ;
for(int i = 0 ; i < len ; i++ )
{
int num = s[i] - '0' ;
if(! tire[p][num]) tire[p][num] = ++tot ;
else cnt++ ;
p = tire[p][num] ;
if(End[p]) Pd = false ;
}
End[p] = true ;
if(cnt == len) return false ;
else return Pd ;
}
signed main()
{
cin >> t ;
while( t-- )
{
cin >> n ; pd = false , tot = 0 ;
memset(tire , 0 , sizeof(tire)) ;
memset(End , 0 , sizeof(End)) ;
while(n--)
{
cin >> s ;
if(!insert(s) ) puts("NO") , pd = true ;
}
if(pd) continue ;
else puts("YES") ;
}
return 0 ;
}

浙公网安备 33010602011771号