HDU 1305 Immediate Decodability HDU 1671 Phone List(字典树)

原创 2012年03月28日 08:08:54

题目链接:

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

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

这两题几乎都是一样,所以就一起贴上来了...........

题意:

每个测试实例先输入一个数N1<=N<=10000),接着输入N个数字串。这些数字串作为电话号码,判断在拨号过程中是否出现干扰的号码,若有干扰的号码则不能打通输出NO,否则输出YES。干扰是这样理解的:一个串T,一个串S,不妨设lengthT<lengthS),如果TS的子串那么就产生干扰,因为假如我要拨S号码,那么我在拨完S号码前一定已经把T号码给拨完了,那么电话就转到T上了。

用字典树先保存所有数据,那么据题意判断是否产生干扰就看每个节点的num值与它的所有存在的子节点的num值之和是否相等,如果不相等那么必然有干扰了。

如果字符串Xn=X1X2....Xn是字符串Ym=Y1Y2....Ym的前缀,有在插入的时候有两种情况:XnYn之前插入,XnYn之后插入。

 (1)如果Xn在Yn之前插入,那么在插入Yn的时候必然经过Xn的路径,此时可以根据判断在这条路径上是否已经有结点被标记已经构成完成的字符串序列来判断是否存在Yn的前缀;

(2)如果Xn在Yn之后插入,那么插入完成之后当前指针指向的结点的next数组中的元素必定不全为NULL。
HDU 1671 AC code:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
bool is_phone;/*判断是否能成功拨打号码*/
struct node
{
    bool flag;/*在数字串最后标记*/
    struct node *next[10];
};
struct node *root;
struct node *newset()/*新建结点*/
{
    struct node *p=(struct node *)malloc(sizeof(struct node));
    for(int i=0;i<10;i++)
    {
        p->next[i]=NULL;
    }
    p->flag=false;/*初始化为false*/
    return p;
}
void insert(char *str)/*建立字典树*/
{
    struct node *p;
    p=root;
    int len=strlen(str);
    for(int i=0;i<len;i++)
    {
        if(p->next[str[i]-'0']==NULL)/*如果以前没有建立过该结点*/
        {
           if(p->flag==false)
           {
			   p->next[str[i]-'0']=newset();/*建立新结点*/
			   p=p->next[str[i]-'0'];
               if(i==len-1)/*只有当指向到数字串末尾时,标记结点为true;*/
               {
                   p->flag=true;
               }
               else
               {
                   p->flag=false;
               }
           }
           else/*否则说明当前建立的数字串覆盖了以前的数字串(当前更长),不能拨打号码*/
           {
               is_phone=false;
               return ;
               
           }
        }
        else
        {
            if(i==len-1&&p->flag==false)/*如果当前号码是以前出现过的号码的前缀(当前更短)*/
            {
                is_phone=false;
                return ;
            }
            p=p->next[str[i]-'0'];
        }
    }
    return ;
}
int del(node *t)/*释放内存*/
{
    if(t==NULL) return 0;
    for(int i=0;i<10;i++)
    {
        if(t->next[i]!=NULL)
        {
            del(t->next[i]);
        }
    }
    free(t);
    return 0;
}
int main()
{
    int ncase,n;
    char str[1001];
    scanf("%d", &ncase);
    while(ncase--)
    {
        root=newset();
        scanf("%d",&n);
        is_phone=true;
        for(int i=0;i<n;i++)
        {
            scanf("%s",str);
            insert(str);
        }
        if(is_phone) printf("YES\n");
        else printf("NO\n");
        del(root);
    }
    return 0;
}        

1305 AC code:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
bool is_phone;/*判断是否能成功拨打号码*/
struct node
{
    bool flag;/*在数字串最后标记*/
    struct node *next[10];
};
struct node *root;
struct node *newset()/*新建结点*/
{
    struct node *p=(struct node *)malloc(sizeof(struct node));
    for(int i=0;i<10;i++)
    {
        p->next[i]=NULL;
    }
    p->flag=false;/*初始化为false*/
    return p;
}
void insert(char *str)/*建立字典树*/
{
    struct node *p;
    p=root;
    int len=strlen(str);
    for(int i=0;i<len;i++)
    {
        if(p->next[str[i]-'0']==NULL)/*如果以前没有建立过该结点*/
        {
           if(p->flag==false)
           {
			   p->next[str[i]-'0']=newset();/*建立新结点*/
			   p=p->next[str[i]-'0'];
               if(i==len-1)/*只有当指向到数字串末尾时,标记结点为true;*/
               {
                   p->flag=true;
               }
               else
               {
                   p->flag=false;
               }
           }
           else/*否则说明当前建立的数字串覆盖了以前的数字串(当前更长),不能拨打号码*/
           {
               is_phone=false;
               return ;
           }
        }
        else
        {
            if(i==len-1&&p->flag==false)/*如果当前号码是以前出现过的号码的前缀(当前更短)*/
            {
                is_phone=false;
                return ;
            }
            p=p->next[str[i]-'0'];
        }
    }
    return ;
}
int del(node *t)
{
    if(t==NULL) return 0;
    for(int i=0;i<10;i++)
    {
        if(t->next[i]!=NULL)
        {
            del(t->next[i]);
        }
    }
    free(t);
    return 0;
}
int main()
{
    int num(1);
    char str[1001];
    while(~scanf("%s",str))
    {
		root=newset();
		is_phone=true;
		insert(str);
		while(scanf("%s",str),*str!='9')
		{
			insert(str);
		}
		if(is_phone) printf("Set %d is immediately decodable\n",num++);
        else printf("Set %d is not immediately decodable\n",num++);
	}
    return 0;
}


 








HDU 1671 Phone List(字典树模板)

布~ Phone List Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav...
  • usher_ou
  • usher_ou
  • 2017年03月12日 20:36
  • 257

HDU 1671 Phone List (字典树入门)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1671 题面: Phone List Time Limit: 3000/1000 ...
  • David_Jett
  • David_Jett
  • 2015年10月08日 22:40
  • 334

(HDU)1671 - Phone List 【字典树】

输入的号码中如果有任意一个号码是另一个号码的前缀,只能拨通最短的那个号码,所以输出NO,否则输出YES。...
  • qq_35504607
  • qq_35504607
  • 2017年03月07日 16:10
  • 374

Hdu 1671 -Phone List (字典树模板)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1671题目大意: 给出nn个字符串,询问是否存在某个串完全为另一个串的前缀分析: 将字符串按长度...
  • SD_Stjean
  • SD_Stjean
  • 2017年07月20日 14:32
  • 87

HDU 1671 Phone List (字典树模板)

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem...
  • u014705673
  • u014705673
  • 2014年07月06日 20:31
  • 718

HDU 1671 Phone List (字典树入门基础题)

题目链接:HDU 1671 Phone List
  • u012377575
  • u012377575
  • 2014年07月16日 15:42
  • 481

hdu 1671 Phone List(字典树·粉刷式标记)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1671 Description Given a list of phone number...
  • theArcticOcean
  • theArcticOcean
  • 2015年08月12日 09:29
  • 661

hdu 1671 Phone List 字典树(静态版)

HDU1671 ------明天就要放清明节4天长假了,今天居然下起了小雨,真是凉飕飕啊。啊......,估计四天假又要虚度了,不行我至少要学点东西。。           《Phone List...
  • Adrian_1
  • Adrian_1
  • 2015年04月02日 20:10
  • 473

【HDU】1671 - Phone List(字典树(动态建树))

点击打开题目 Phone List Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav...
  • wyg1997
  • wyg1997
  • 2016年08月04日 16:40
  • 134

HDU 1671 Phone List(字典树寻找前缀)

题目意思很清楚:就是判断输入的电话号码中是否有号码是其他号码的前缀,很显然要用到字典树。根据分析可知:   如果字符串Xn=X1X2....Xn是字符串Ym=Y1Y2....Ym的前缀,有在插入的时...
  • u013615904
  • u013615904
  • 2015年08月14日 10:28
  • 182
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU 1305 Immediate Decodability HDU 1671 Phone List(字典树)
举报原因:
原因补充:

(最多只允许输入30个字)