UVA11362 Phone list(Trie树模板)

题目链接

题意:

共t组数据,给定n个长度不超过10的字符串,问其中是否存在两个数S,T,使得S是T的前缀

思路:

建立一个字典树,然后每输入一个字符串,再插入这个字符的过程中+两个判断,之前是否有字符串是此字符串的前缀,该字符串是不是之前字符串的前缀

AC:

#include<cstring>
#include<cstdio>
using namespace std;

int Trie[100005][15], tot = 1;
bool book[100005], vis[100005], flag = 0;
char s[100005];
inline int read()
{
    int f=1,x=0;
    char ch=getchar();
    while(ch<'0' || ch>'9') {if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}

void Insert(char *s){
	int len = strlen(s);
	int u = 1;
	for(int i = 0; i < len; ++i) {
		int c = s[i] - '0';
		if( !Trie[u][c] ) {
			Trie[u][c] = ++tot;
		}
		u = Trie[u][c];
		if(i == len - 1 && vis[u] == true && book[u] != true){
			flag = 1;
			return ;
		}
		vis[u] = true;
		if(book[u] && i != (len - 1)) {
			flag = 1;
			return ;
		}
	}
	book[u] = true;
	return ;
}
void init(){
	memset(Trie, 0, sizeof(Trie));
	memset(book, 0, sizeof(book));
	memset(vis, 0, sizeof(vis));
	tot = 1;
}
int main() {
	int T, N;
	//char s[20];
	T = read();

	while(T--) {
		init();
		flag = 0;
		N = read();
		for(int i = 0; i < N; ++i) {
			scanf("%s", s);
			if(!flag)
				Insert(s);
		}
		if(flag) {
			printf("NO\n");
		}else {
			printf("YES\n");
		}
	}
	return 0;
}
发布了199 篇原创文章 · 获赞 156 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/Harington/article/details/99725796
今日推荐