题意:给你的电话号码当中,若出现一个电话的前缀是另一个电话则输出NO,不存在则输出YES
思路:想暴力?你爆的不止是时间,而且还爆空间
题解:字典树,一个相当有用的数据结构,时间空间都无压力,字典树上的一个改动就在结构体加一个字符结束的标记即可
#include <iostream>
#include <string>
using namespace std;
struct Trie{
struct Trie *child[10];
bool isPerfix;
}*root;//字典树
class Trie_Function{
public:
Trie* Trie_Init();//创建新结点并初始化
int Trie_Search(char *ch);
void Trie_Insert(char *ch);
};
Trie* Trie_Function::Trie_Init(){
Trie *node = new Trie;
for(int i = 0; i<10; i++)
node->child[i] = NULL;
node->isPerfix = false;
return node;
}
void Trie_Function::Trie_Insert(char *ch){
Trie *newNode,*nowNode;
int len = strlen(ch);
nowNode = root;
for(int i = 0; i<len; i++){
if(nowNode->child[ch[i]-'0']!=NULL){//存在
nowNode = nowNode->child[ch[i]-'0'];
}else{
newNode = Trie_Init();
nowNode->child[ch[i]-'0'] = newNode;
nowNode = newNode;
}
if(i == len - 1) nowNode->isPerfix = true;
}
}
int Trie_Function::Trie_Search(char *ch){
int len = strlen(ch);
Trie *nowNode = root;
bool flag = 0;
for(int i = 0; i<len; i++){
if(nowNode->child[ch[i]-'0']){//已存在
if(nowNode->isPerfix == true)//标记
{
flag = 1;
break;
}
else
nowNode = nowNode->child[ch[i]-'0'];
}
else{
return 0;
}
}
return flag;
}
void freedom(Trie *p)
{
for(int i = 0; i<10; i++)
if(p->child[i]!=NULL)
freedom(p->child[i]);
free(p);
}
int main()
{
char list[10010][15];
Trie_Function f;
char number[15];
int T,n;
cin>>T;
while(T--)
{
root = f.Trie_Init();//初始化根节点
cin>>n;
getchar();
for(int i = 0; i<n; i++)
{
gets(number);
f.Trie_Insert(number);
strcpy(list[i], number);
}
int temp = 0;
for(i = 0; i<n; i++)
{
strcpy(number, list[i]);
temp = f.Trie_Search(number);
if(temp)
{
cout<<"NO"<<endl;
break;
}
}
if(temp==0)
cout<<"YES"<<endl;
}
return 0;
}