POJ 3630 Phone List 字典树

         今晚学了字典树,找来一题熟悉熟悉,直接套模板,一开始在Sicily过了,但在POJ 超时,囧,看了别人的解题报告,直接开个10000数组来储存节点,而不是插入时再new一个,就这样AC掉了

#include <iostream>

#include <stdio.h>

#include <memory.h>

#include <string.h>



using namespace std;



int nodenum;

bool find_prex;



struct Trie_node

{

	bool isStr;

	Trie_node *next[10];

	Trie_node()

	{

		isStr = false;

		memset(next, NULL, sizeof(next));

	}

};



Trie_node node[100000];



class Trie

{

public:

	Trie();

	void clear();

	void insert(char *);

private:

	Trie_node *root;

};



void Trie::clear()

{

	for (int i = 0; i < nodenum; i++)

	{

		node[i].isStr = false;

		memset(node[i].next, NULL, sizeof(node[i].next));

	}

}



Trie::Trie()

{

	root = &node[0];

}



void Trie::insert(char * word)

{

	//当找到一个number不符合题意的话,就不做插入操作

	if (find_prex) return;  

	

	Trie_node *p = root;



	while (*word)

	{

		//当在树中找到一个单词是插入单词的前缀时,停止查找

		if (p->isStr)

		{	

			find_prex = true; 

			return ;

		}



		if (p->next[*word-'0'] == NULL)

		{

			Trie_node *tmp = &node[nodenum];

			p->next[*word-'0'] = tmp;

			nodenum++;

		}

		p = p->next[*word-'0'];

		word++;

	}

	//判断树中是否有元素与插入的number相同

	if (p->isStr)

		find_prex = true;



	//判断树中是否有元素的前缀是插入单词

	for (int i = 0; i < 10; i++)

		if (p->next[i] != NULL)

		{

			find_prex = true;

			return ;

		}



	p->isStr = true;

}





int main()

{

	Trie t;

	int cases, n;

	char number[11];



	cin >> cases;



	while (cases--)

	{

		nodenum = 1;

		find_prex = false;

		cin >> n;



		for (int i = 0; i < n; i++)

		{

			scanf("%s", number);

			if (!find_prex)

				t.insert(number);

		}



		if (!find_prex)

			cout << "YES" << endl;

		else

			cout << "NO" << endl;

		t.clear();

	}

}

你可能感兴趣的:(list)