POJ3630/HDU-1671 Phone List,字典树静态建树!

Phone List

    POJ动态建树TLE了~~~

    题意:拨打某个电话时可能会因为和其他电话号码的前几位重复而导致错误,现在给出一张电话单,求是否有某个电话是其他电话的前缀。是则输出NO,否则输出YES。

    思路:字典树模板题了,但有一个动态建树每次都要清空内存这个很重要,很容易导致MLE了。这个题插入和查找可以放在一起,这便是字典树的强大之处。

struct Tree
{
    bool f;
    Tree *next[N];
};
int insert(Tree *root,char *s)
{
    int sign=0;
    Tree *p=root;
    while(*s!='\0')
    {
        if(p->next[*s-'0']==NULL)
        {
            Tree *temp=new Tree;
            for(int i=0; i<N; i++) temp->next[i]=NULL;
            temp->f=false;
            p->next[*s-'0']=temp;
        }
        if(p->f) sign=1;
        p=p->next[*s-'0'];
        s++;
    }
    p->f=true;//构成了一个单词或者电话
    for(int i=0; i<N&&!sign; i++) if(p->next[i]!=NULL)  sign=1;//这条路径还可以走下去,说明前面的都重复了
    return sign;
}
void del(Tree *root)
{
    for(int i=0; i<N; i++)
        if(root->next[i]!=NULL)
            del(root->next[i]);
    delete(root);
}
int main()
{
    int t,n;
    char s[15];
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        int f=0;
        Tree *root=new Tree;
        for(int i=0;i<N;i++) root->next[i]=NULL;//初始化子节点;
        root->f=false;
        for(int i=0; i<n; i++)
        {
            scanf("%s",s);
            if(!f) f=insert(root,s);
        }
        if(f) printf("NO\n");
        else printf("YES\n");
        del(root);//每次都要清空内存;
    }
    return 0;
}


/*****************************************
*****************   LYQ    ***************
*****************   YES    ***************
*UserID: secrecy                         *
*RunOJ:                                  *
*RunID:                                  *
*Submit time:                            *
*Language: G++                           *
*Result: Accepted                        *
*time:                                   *
*Memory:                                 *
*Length:                                 *
*School: NYIST                           *
*Blog: http://blog.csdn.net/nyist_tc_lyq *
*QQ:                                     *
*Tel:                                    *
*****************************************/

     

                                                                           POJ-3630

    一模一样的题,杭电上用动态建树过了,这里就超时了,建树反复分配和释放内存的问题,所以可以用静态树进行优化一下,开一个Tree的数组,注意开大一点,太大或太小都会MLE。数组开60010差不多可以了。

int cnt;
struct Tree
{
    bool f;
    Tree *next[N];
};
Tree memory[60005];
int insert(Tree *root,char *s)
{
    int sign=0;
    Tree *p=root;
    while(*s!='\0')
    {
        if(p->next[*s-'0']==NULL)
        p->next[*s-'0']=&memory[cnt++];
        if(p->f) sign=1;
        p=p->next[*s-'0'];
        s++;
    }
    p->f=true;
    for(int i=0; i<N&&!sign; i++) if(p->next[i]!=NULL)  sign=1;
    return sign;
}
int main()
{
    int t,n;
    char s[15];
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        int f=0;
        cnt=0;
        memset(memory,0,sizeof(memory));//清空
        Tree *root=&memory[cnt++];//已经开辟好了内存,不用每次都分配了。
        for(int i=0; i<n; i++)
        {
            scanf("%s",s);
            if(!f) f=insert(root,s);
        }
        if(f) printf("NO\n");
        else printf("YES\n");
    }
    return 0;
}
//能理解但是不会用,关于内存分配和释放这一块比较薄弱,貌似平时用的也不多~~

/*****************************************
*****************   LYQ    ***************
*****************   YES    ***************
*UserID: secrecy                         *
*RunOJ:                                  *
*RunID:                                  *
*Submit time:                            *
*Language: G++                           *
*Result: Accepted                        *
*time:                                   *
*Memory:                                 *
*Length:                                 *
*School: NYIST                           *
*Blog: http://blog.csdn.net/nyist_tc_lyq *
*QQ:                                     *
*Tel:                                    *
*****************************************/


转载于:https://www.cnblogs.com/nyist-TC-LYQ/p/7208130.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值