一本通 电话列表

ACwing161

solution

假设已经插入了 \(i\) 个字符串,现在要插入一个字符串 \(str\) 那么此时 \(str\) 产生不兼容的方式只有两种

  1. \(str\) 是前 \(i\) 个已插入字符串的前缀
  2. \(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 ;
}
posted @ 2022-04-05 17:46  Simon_...sun  阅读(33)  评论(0)    收藏  举报