字典树板子题

1.C - 统计难题 HDU - 1251
https://vjudge.net/contest/446782#problem/C

//字典树增删查板子
struct tree
{
    tree *next[26];
    int flag;
    tree()
    {
        flag=1;
        memset(next,NULL,sizeof(next));
    }
}*root;
void add(char *s)
{
    int len=strlen(s);
    tree *p=root,*q;
    for(int i=0;i<len;i++)
    {
        int id=s[i]-'a';
        if(p->next[id]==NULL)
        {
            q=new tree();
            p->next[id]=q;
            p=p->next[id];
        }
        else
        {
            p=p->next[id];
            (p->flag)++;
        }
    }
}
int query(char *s)
{
    int len=strlen(s);
    tree *p=root;
    for(int i=0;i<len;i++)
    {
        int id=s[i]-'a';
        p=p->next[id];
        if(p==NULL)return 0;
    }
    return p->flag;
}
void free(tree *t)
{
    if(t==NULL)return ;
    for(int i=0;i<26;i++)
    {
        if(t->next[i])free(t->next[i]);
    }
    delete(t);
}
int main()
{
    char s[15];
    root =new tree();
    while(gets(s)&&s[0]!='\0')
    {
        add(s);
    }
    while(gets(s))
    {
        printf("%d\n",query(s));
    }
    free(root);
    return 0;
}

//一种简单写法
map<string,int>mp;
char s[15];
void add(char *s)
{
    char ss[15];
    for(int i=0;s[i];i++)
    {
        ss[i]=s[i];
        ss[i+1]='\0';
        mp[ss]++;
    }
}
int main()
{
    while(gets(s)&&s[0]!='\0')add(s);
    while(gets(s))printf("%d\n",mp[s]);
    return 0;
}

2.A - Shortest Prefixes POJ - 2001
找到flag为1的地方
若没有输出本身

char s[1010][25];
struct tree
{
    int flag;
    tree *next[26];
    tree()
    {
        flag=1;
        memset(next,NULL,sizeof(next));
    }
}*root;
void add(char *s)
{
    int len=strlen(s);
    tree *q=root,*p;
    for(int i=0;i<len;i++)
    {
        int id=s[i]-'a';
        if(q->next[id]==NULL)
        {
            p=new tree();
            q->next[id]=p;
            q=q->next[id];
        }
        else
        {
            q=q->next[id];
            (q->flag)++;
        }
    }
}
int query(char *s)
{
    int len=strlen(s);
    tree *q=root;
    for(int i=0;i<len;i++)
    {
        int id=s[i]-'a';
        q=q->next[id];
        if(q!=NULL)
        {
            if(q->flag==1)return i;
        }
        else return len-1;
    }
    return len-1;
}
void free(tree *t)
{
    if(t==NULL)return;
    for(int i=0;i<26;i++)
    {
        if(t->next[i])free(t->next[i]);
    }
    delete(t);
}
int main()
{
    int cnt=0;
    root=new tree();
    while(~scanf("%s",s[cnt]))
    {
        add(s[cnt]);
        cnt++;
    }
    for(int i=0;i<cnt;i++)
    {
        int x=query(s[i]);
        char ss[25];
        strncpy(ss,s[i],x+1);
        //没有\0会出现乱码
        ss[x+1]='\0';
        printf("%s %s\n",s[i],ss);
    }
    free(root);
    return 0;
}

3.D - Phone List HDU - 1671

int t,n;
char s[10010][12];
struct tree
{
    int flag;
    tree *next[12];
    tree()
    {
        flag=1;
        memset(next,NULL,sizeof(next));
    }
}*root;
void add(char *s)
{
    int len=strlen(s);
    tree *q=root,*p;
    for(int i=0;i<len;i++)
    {
        int id=s[i]-'0';
        if(q->next[id]==NULL)
        {
            p=new tree();
            q->next[id]=p;
            q=q->next[id];
        }
        else
        {
            q=q->next[id];
            (q->flag)++;
        }
    }
}
bool query(char *s)
{
    int len=strlen(s);
    tree *q=root;
    for(int i=0;i<len;i++)
    {
        int id=s[i]-'0';
        q=q->next[id];
        if(q==NULL)return false;
        else
        {
            if(q->flag==1)return true;
            if(i==len-1)return false;
        }
    }
}
void free(tree *t)
{
    if(t==NULL)return;
    for(int i=0;i<10;i++)
    {
        if(t->next[i])free(t->next[i]);
    }
    delete(t);
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        root=new tree();
        memset(s,0,sizeof(s));
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",&s[i]);
            add(s[i]);
        }
        int flag=0;
        for(int i=1;i<=n;i++)
        {
            if(query(s[i])==false)
            {
                flag=1;
                break;
            }
        }
        if(flag==1)printf("NO\n");
        else printf("YES\n");
        free(root);
    }
    return 0;
}

4.B - Babelfish POJ - 2503

map<string,string>mp;
char str[25],a[12],b[12],s[12];
int main()
{
    while(gets(str)&&str[0]!='\0')
    {
        sscanf(str,"%s %s",a,b);
        mp[b]=a;
        memset(a,'\0',sizeof(a));
        memset(b,0,sizeof(b));
    }
    while(~scanf("%s",s))
    {
        if(mp.find(s)==mp.end())cout<<"eh\n";
        else cout<<mp[s]<<"\n";
    }
    return 0;
}

5.H - Xor Sum HDU - 4825
把数用二进制储存,不够32位的前补零操作。

int t,n,m;
struct tree
{
    int flag;
    tree *next[3];
    tree()
    {
        flag=1;
        memset(next,NULL,sizeof(next));
    }
}*root;
void add(int *a)
{
    tree *q=root,*p;
    for(int i=31;i>=0;i--)
    {
        if(q->next[a[i]]==NULL)
        {
            p=new tree();
            q->next[a[i]]=p;
            q=q->next[a[i]];
        }
        else
        {
            q=q->next[a[i]];
            (q->flag)++;
        }
    }
}
void free(tree *t)
{
    if(t==NULL)return;
    tree *q=t;
    for(int i=0;i<2;i++)
    {
        if(q->next[i])free(q->next[i]);
    }
    delete(t);
}
int query(int *a)
{
    tree *q=root;
    int sum=0;
    for(int i=31;i>=0;i--)
    {
        int id=1-a[i];
        if(q->next[id]==NULL)
        {
            q=q->next[1-id];
            if((1-id)==1)sum+=(int)pow(2,i);
        }
        else
        {
            q=q->next[id];
            if(id==1)sum+=(int)pow(2,i);
        }
    }
    return sum;
}
int main()
{
    scanf("%d",&t);
    for(int vv=1;vv<=t;vv++)
    {
        root=new tree();
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            int x;scanf("%d",&x);
            int a[35];int cnt=0;
            while(x>0)
            {
                a[cnt++]=x%2;
                x=x/2;
            }
            for(int i=cnt;i<32;i++)a[i]=0;
            add(a);
        }
        printf("Case #%d:\n",vv);
        for(int i=1;i<=m;i++)
        {

            int x;scanf("%d",&x);
            int a[35];int cnt=0;
            while(x>0)
            {
                a[cnt++]=x%2;
                x=x/2;
            }
            for(int i=cnt;i<32;i++)a[i]=0;
            printf("%d\n",query(a));
        }
        free(root);
    }
    return 0;
}

6.G - IMMEDIATE DECODABILITY POJ - 1056
把每个01串存入字典树,然后查找,看是否存在一个01串的flag都>1。

struct tree
{
    int flag;
    tree *next[3];
    tree()
    {
        flag=1;
        memset(next,NULL,sizeof(next));
    }
}*root;
void add(char *s)
{
    tree *q=root,*p;
    int len=strlen(s);
    for(int i=0;i<len;i++)
    {
        int id=s[i]-'0';
        if(q->next[id]==NULL)
        {
            p=new tree();
            q->next[id]=p;
            q=q->next[id];
        }
        else
        {
            q=q->next[id];
            (q->flag)++;
        }
    }
}
void free(tree *t)
{
    if(t==NULL)return ;
    for(int i=0;i<2;i++)
    {
        if(t->next[i])free(t->next[i]);
    }
    delete (t);
}
bool query(char *s)
{
    int len=strlen(s);
    tree *q=root;
    for(int i=0;i<len;i++)
    {
        int id=s[i]-'0';
        q=q->next[id];
        if(q&&(q->flag)==1)return false;
    }
    return true;
}
char s[10][12];
int main()
{
    int vv=0;
    while(~scanf("%s",s[0]))
    {
        vv++;
        root=new tree();
        add(s[0]);
        int cnt=0;
       // printf("6665\n");
        for(;;)
        {
            scanf("%s",s[++cnt]);
            if(s[cnt][0]=='9')break;
            add(s[cnt]);
        }
        //printf("6665\n");
        int flag=0;
        for(int i=0;i<cnt;i++)
        {
            if(query(s[i])){flag=1;break;}
        }
        if(flag==0)printf("Set %d is immediately decodable\n",vv);
        else printf("Set %d is not immediately decodable\n",vv);
        memset(s,0,sizeof(s));
        free(root);
    }
    return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值