hdu 1305 字典树

http://acm.hdu.edu.cn/showproblem.php?pid=1305

题目大意:给出几组只包含0和1的字符串,对于每组字符串,判断是否有一些串是另一些串的前缀;

思路:将一组中的每个字符串依次加入字典树。

1.若加入某串过程中若遇到了叶子节点,则说明存在当前串的字串;(判断叶子节点的方法见注释)

2.若加入某串过程中始终没有添加新节点,则说明当前串是其他串的字串;

PS:本题的测试实例弱爆了,不考虑第二种情况竟然能过,不过很容易就能举出反例证明第二种情况的必要性;

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
struct node
{
	node* zero;
	node* one;
	node(){
		zero=NULL;
		one=NULL;
	}
}*root;
int flag=0;
void insert(char* s)
{
	int i,len;
	int mark=1;  //mark标记p指向的节点是否为新节点
	int mark2=0; //mark2标记s插入过程中是否添加新的节点
	node* p=root;
	len=strlen(s);
	if(flag==1) return;
	for(i=0;i<len;i++){
		if(s[i]=='0'){
			if(!mark&&p->zero==NULL&&p->one==NULL){//节点为叶子的条件:
				flag=1;return;  //该节点不是新节点且该节点没有孩子节点
			}
			if(p->zero==NULL){
				p->zero=new node();
				p=p->zero;
				mark=1;
				mark2=1;
			}
			else{
				p=p->zero;
				mark=0;
			}
		}
		else{
			if(!mark&&p->zero==NULL&&p->one==NULL){
				flag=1;return;
			}
			if(p->one==NULL){
				p->one=new node();
				p=p->one;
				mark=1;
				mark2=1;
			}
			else{
				p=p->one;
				mark=0;
			}
		}
	}
	if(mark2==0) flag=1;
	return;
}
//释放内存
void freedom(node* p)
{
	if(p->zero!=NULL) freedom(p->zero);
	if(p->one!=NULL) freedom(p->one);
	delete p;
}
int main()
{
	char s[11];
	int T=1;
	root=new node();
	while(scanf("%s",s)!=EOF){
		if(s[0]=='9'){
			if(flag==0)
				printf("Set %d is immediately decodable\n",T++);
			else
				printf("Set %d is not immediately decodable\n",T++);
			freedom(root);
			root=new node();
			flag=0;
			continue;
		}
		insert(s);
	}
	return 0;
}


你可能感兴趣的:(数据结构,c,算法,ACM,字典树)