HDU 1671 Phone List

题意:给你的电话号码当中,若出现一个电话的前缀是另一个电话则输出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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值