水题不水之字典树(Tire tree)

        今天碰到了一个水题不水。题目链接如下: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);
}
	


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值