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;
}