题目地址
学习博客1(有图)
学习博客2(有例题)
【题意】若没有串是任意一个串的前缀,输出Yes
#include <bits/stdc++.h>
using namespace std;
#define ll long long;
const int N = 100005;
int T[N][10]; ///字典树,此题为数字,每个节点下有10个子节点
int num[N]; ///num[i]:以第i个节点表示的串为前缀的串个数
int pos; ///总节点数
char word[1005][11]; ///此题每个串最多10数字
void Insert(char word[]) ///将串插入字典树
{
int root = 0;
int len = strlen(word);
for(int i = 0; i < len; i++)
{
int tmp = word[i] - '0';
if(T[root][tmp] == 0)
T[root][tmp] = pos++;
root = T[root][tmp]; ///根节点下移
num[root]++;
}
///平常字典树需要加个判断,判断是否构成一个单词
}
int Find(char word[]) ///在字典树中查找串
{
int root = 0;
for(int i = 0; word[i]; i++)
{
int tmp = word[i] - '0';
if(T[root][tmp] == 0) ///没有这样的前缀
return 0;
root = T[root][tmp]; ///根节点下移,继续查串的下一位
}
return num[root]; ///返回以该串为前缀的字符串数目
}
int main()
{
int t, n;
cin>>t;
for(int k = 1; k <= t; k++)
{
memset(T, 0, sizeof(T));
memset(num, 0, sizeof(num));
memset(word, 0, sizeof(word));
pos = 1;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%s", &word[i]);
Insert(word[i]);
}
bool flag = 1;
for(int i = 1; i <= n; i++)
{
if(flag)
{
if(Find(word[i]) > 1)
{
flag = 0;
break;
}
}
}
if(flag)
cout<<"Case #"<<k<<": Yes"<<'\n';
else
cout<<"Case #"<<k<<": No"<<'\n';
}
return 0;
}