题目大意:一个数不能是另一个数开头的子串,trie树
暴力解法:然后细细一想,既然是判断相同串是否存在,那我直接将串进行排序将第一位相同的串排在一起再进行判断操作,就大大优化了搜索时间。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
string s[100005];
int main()
{
char p[12];
int t,flag=0,n,i,j;
scanf("%d",&t);
while(t--)
{
flag=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%s",&p);
s[i]=p;
}
sort(s,s+n);
for(int i=1;i<n;i++)
{
if(s[i].size()>s[i-1].size())
{
for(j=0;j<s[i-1].size();j++)
if(s[i][j]!=s[i-1][j])
break;
if(j==s[i-1].size())
flag=1;
}
}
if(flag) printf("NO\n");
else printf("YES\n");
}
return 0;
}
trie树的解法:
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
struct tree {
int flag;//标记此处是否是串
tree* next[10];//指向子节点
tree() {
flag = 0;
memset(next, NULL, sizeof(next));
}
};
tree *root = new tree;//建立根节点,根节点不存字符
int tree_insert(string t) {//向trie树中插入串
tree* p = root;
int flag = 0;
for (int i = 0; i < t.size(); i++) {//循环串的每个字符
int k = t[i] - '0';
if (p->next[k] == NULL) {//没有出现过
p->next[k] = new tree;
flag = 1;
}
p = p->next[k];//向下移动
if (p->flag == 1)return 0;
}
p->flag = 1;
if (flag)return 1;
else return 0;
}
int main() {
int T;
cin >> T;
while (T--) {
int flag = 1;
int n;
cin >> n;
while (n--) {
string t;
cin >> t;
if (flag)flag = tree_insert(t);
}
if (flag)cout << "YES" << endl;
else cout << "NO" << endl;
}
}