今天碰到了一个水题不水。题目链接如下:http://acm.nyist.net/JudgeOnline/problem.php?pid=163
第一感觉就是用字符串存储,然后一个一个地比较,然后,结果你们懂的,显然是TLE(超时),直接给我一个TLE错误,我了个去,然后 没办法才用的字典树。
又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来节约存储空间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。
提交的最后AC代码如下所示:
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
struct TireTree{
TireTree* child[10];
int number;
};
void DestroyTireTree(TireTree* root){//destroy a tire tree
if(!root)//root is null
return;
for(int i= 0; i< 10; ++i){//destroy child
DestroyTireTree(root->child[i]);
}
delete root;//destroy root
}
TireTree* CreateNode(int inode){
TireTree* node = new TireTree;
node->number = inode;
memset(node->child, 0, sizeof(TireTree*)*10);//child is null
return node;
}
bool InsertToTireTree(TireTree* root, int iNode, int* bit, int ilen, int iStep){
if(root->number){
return false;
}
if(iStep == ilen-1){//the last bit
if(root->child[bit[iStep]]){//has a prefix
return false;
}else{
root->child[bit[iStep]] = CreateNode(iNode);
return true;
}
}else{
if(!root->child[bit[iStep]]){//child is null
root->child[bit[iStep]] = CreateNode(0);
}
return InsertToTireTree(root->child[bit[iStep]], iNode, bit, ilen, iStep+1);
}
}
void HandleEachCase();
int main(){
int iCaseCount;
cin>>iCaseCount;
while(iCaseCount--){
HandleEachCase();
}
}
void HandleEachCase(){
int n;
int number[100000];
scanf("%d", &n);
for(int i= 0; i< n; ++i){
scanf("%d", number+i);
}
int bit[10];
int ilen;
TireTree* root = CreateNode(0);
int tmp;
bool ok= true;
for(int i= 0; i< n; ++i){
tmp = number[i];
ilen = 0;
while(tmp){
bit[ilen++]= tmp%10;
tmp/= 10;
}
reverse(bit, bit+ ilen);
if(!InsertToTireTree(root, number[i], bit, ilen, 0)){
ok = false;
break;
}
}
if(ok){
cout<<"YES\n"<<endl;
}else{
cout<<"NO\n";
}
DestroyTireTree(root);
}