#include<stdio.h>
#include<iostream>
const int MAX=100005;
class Trie{
public:
Trie() {clear();}
int idx(char c) {return c-'0';}
void clear() { size=1;memset(ch[0],0,sizeof(ch[0]));}
bool insert(char* s);
private:
int size;
int ch[MAX][10];
int val[MAX];
};
//val[u]=2表示 结点u是一个字符串的尾字符
//val[u]=1表示 结点u是一个字符串的中间字符
bool Trie::insert(char* s)
{
int len=strlen(s);
int c=0,u=0;
for(int i=0;i<len;i++)
{
c=idx(s[i]);
if(0==ch[u][c]){
memset(ch[size],0,sizeof(ch[size]));
val[size]=0;
ch[u][c]=size++;
}
//如果该结点是某一字符串的尾字符
if(val[u]==2) return false;
//否则,则标志该字符为某一字符的中间字符
val[u]=1;
u=ch[u][c];
}
//标志某字符串的尾字符
//若尾字符已经是一字符串的中间字符
if(val[u]) return false;
//否则标志该字符为字符串的尾字符
val[u]=2;
return true;
}
char s[100];
Trie trie;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
//每次测试都要将Trie树重新初始化
trie.clear();
scanf("%d",&n);
int ans=1;
for(int i=0;i<n;i++)
{
scanf("%s",&s);
if(ans&!trie.insert(s))
{
ans=0;
printf("%s\n","NO");
}
}
if(ans)
printf("%s\n","YES");
}
}
注意事项:
1.测试数据
2 2 1 12 2 12 1 NO NO
即一定要考虑到 123 1234 即 1234 123,两种输入结果都是NO
2.
Trie树用数组来实现,时间效率比较高
3.每次测试时,都必须将Trie树重新初始化。
思路:先将字符串排序,然后比较相邻的两个字符串即可
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int MAX=10010;
int main()
{
string str[MAX];
int test;
scanf("%d",&test);
while(test--){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
cin>>str[i];
sort(str+0,str+n);
bool flag=true;
for(int i=0;i<n-1;i++)
{
int len=str[i].length();
string tmp=str[i+1].substr(0,len);
if(str[i]==tmp)
{
flag=false;
break;
}
}
if(flag) printf("%s\n","YES");
else
printf("%s\n","NO");
}
}