Trie树【UVA11362】Phone List

Description

给定\(n\)个长度不超过\(10\)的数字串,判断是否有两个字符串\(A\)\(B\),满足\(A\)\(B\)的前缀,若有,输出NO,若没有,输出YES

一道\(Trie\)树裸题,我交了20次.

呜呜呜呜,难受.

刚开始是看错题,有的话输出"NO",没有输出“YES”什么鬼题啊!!!

一眼看到就会切了的.害得我交了20次啊!

定义数组:

  \(ok[v]\)表示以\(v\)为结尾的字符串是否出现过.

  \(cnt[u]\)代表当前节点被遍历过几次,判断插入的某字符串的末尾是否被经历过两次以上.

输出即可.

记得\(memset\).

代码

#include<cstdio>
#include<cstring>
#define clear(a) memset(a,0,sizeof a) 
#define R register
using namespace std;
int tri[100005][12],n,T,rt,tot,cnt[100005];
char s[15];
bool flg,ok[100005];
inline void insert(int u,char *s)
{
	int len=strlen(s);
	for(R int i=0;i<len;i++)
	{
		int v=s[i]-'0';
		if(!tri[u][v])
			tri[u][v]=++tot;
		u=tri[u][v];
		cnt[u]++;
		if(ok[u])flg=true;
	}
	ok[u]=true;
	if(cnt[u]>1)flg=true;
}
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		flg=false;
		clear(tri);clear(ok);
		clear(cnt);tot=0;
		scanf("%d",&n);
		for(R int i=1;i<=n;i++)
		{
			scanf("%s",s);
			insert(rt,s);	
		}
		puts(flg?"NO":"YES");
	}
}
posted @ 2018-10-14 21:45  顾z  阅读(212)  评论(0编辑  收藏  举报