题解 SP4033 【PHONELST - Phone List】

水一发trie板子~

先说这个题怎么套上板子
首先我们判断是否有前缀可以边插入边判断
当我们经过了一个完整的字符串(即当前节点到了一个有标记的节点上)
就是有前缀
我们当然也可以无脑先判断一发(比如我这个)
然后无脑插入就是
减少了一定的编程难度


然后我丧心病狂异想天开写了一发动态的trie
指针警告
好处是内存省下来了
当然删除的时间上来说是省不下来了
具体看代码(代码向预警

#include <iostream>
#include <cstdio>
#include <string>

using namespace std;
//字典集合大小 
const int Z=10;
struct trie{
	//Z个子节点 
    trie *ch[Z];
    //是否存在字符串的标记挂载 
    bool vst;
}rt,*root=&rt;//根节点 
//输入用的字符串 
string input;

void insert(string str)
{
    if (str.size()<1)return ;//空字符串返回 
    trie *now=root;//从根节点开始向下插入 
    for (register int i=0;i<str.size();i++)
    {
        int num=str[i]-'0';//子节点下标 
        if (now->ch[num]==NULL)//需要开一个新的节点 
        {
            now->ch[num]=new trie();//纳新 
            //初始化节点(也可以写到构造函数里 
            for (register int j=0;j<Z;j++)
            {
                now->ch[num]->ch[j]=NULL;//设置成空 
                now->ch[num]->vst=false;//设置不存在当前子节点表示的字符串 
            }
            now=now->ch[num];//向下一个节点移动 
        }
        else now=now->ch[num];//向下一个节点移动 
    }
    now->vst=true;//挂载当前字符串 
}

bool find(string str)
{
    if (str.size()<1)return true;//空字符串走人 
    trie *now=root;//从根节点开始 
    for (register int i=0;i<str.size();i++)
    {
        int num=str[i]-'0';//下标 
        //如果存在没有插入的节点,而且没有经过任何一个完整的字符串,
		//一定是不存在任何一个字符串与其为前缀关系 
        if (now->ch[num]==NULL)return false;
        else
        {
        	//经过一个完整的字符串,即经过的这个字符串
			//是str的前缀 
        	if (now->ch[num]->vst)return true;
        	now=now->ch[num];//向下一个节点移动 
		}
    }
    //存在另一个字符串包含这个字符串
	//即有另一个字符串使得这个字符串是其前缀 
    return true;
}
//无脑删除,回收空间 
void dfs(trie *now)
{
	for (register int i=0;i<10;i++)
	{
		if (now->ch[i]!=NULL)
			dfs(now->ch[i]);
	}
	if (now!=root)delete now; 
}
//重新建树 
void build()
{
	dfs(root);
	for (register int i=0;i<10;i++)
	{
		root->ch[i]=NULL;
	}
	root->vst=false;
}

int main()
{
    int T,n;
    cin>>T;
    while (T--)
    {
    	bool flag=false;
    	//先重新建空树 
    	build();
    	cin>>n;
    	while (n--)
    	{
    		cin>>input;
    		//只要是存在前缀关系就行 
    		flag=find(input)||flag;
    		insert(input);
		}
		//存在即NO 
		puts(flag?"NO":"YES");
	}
    return 0;
}
posted @ 2019-07-21 16:34  小金羊  阅读(188)  评论(0编辑  收藏  举报