• 2016"百度之星"


    Problem C
    Accepts: 832
    Submissions: 6612
    Time Limit: 2000/1000 MS (Java/Others)
    Memory Limit: 131072/131072 K (Java/Others)
    Problem Description

    度熊手上有一本神奇的字典,你可以在它里面做如下三个操作:

    1、insert : 往神奇字典中插入一个单词

    2、delete: 在神奇字典中删除所有前缀等于给定字符串的单词

    3、search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符串

    Input

    这里仅有一组测试数据。第一行输入一个正整数N(1≤N≤100000)N (1leq Nleq 100000)N(1≤N≤100000),代表度熊对于字典的操作次数,接下来NNN行,每行包含两个字符串,中间中用空格隔开。第一个字符串代表了相关的操作(包括: insert, delete 或者 search)。第二个字符串代表了相关操作后指定的那个字符串,第二个字符串的长度不会超过30。第二个字符串仅由小写字母组成。
    Output

    对于每一个search 操作,如果在度熊的字典中存在给定的字符串为前缀的单词,则输出Yes 否则输出 No。
    Sample Input

    5
    insert hello
    insert hehe
    search h
    delete he
    search hello

    Sample Output

    Yes
    No

    用Trie树模拟三种操作即可:

    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<cstdio>
    using namespace std;
    const int maxnode=1000000+10;
    struct Trie
    {
        int ch[maxnode][27];
        int val[maxnode];
        int sz;
        void clear(){sz=1;memset(ch[0],0,sizeof(ch[0]));}
        int idx(char c){return c-'a';}
    
        void insert(const char *s)
        {
            int u=0,n=strlen(s);
            for(int i=0;i<n;i++){
                int c=idx(s[i]);
                if(!ch[u][c]){
                    memset(ch[sz],0,sizeof(ch[sz]));
                    val[sz]=1;
                    ch[u][c]=sz++;
                }
                else val[ch[u][c]]++;
                u=ch[u][c];
            }
        }
        bool search(const char *s)
        {
            int u=0,len=strlen(s);
            for(int i=0;i<len;i++){
                int c=idx(s[i]);
                //cout<<val[ch[u][c]]<<endl;
                if(!ch[u][c]||!val[ch[u][c]])return 0;
                u=ch[u][c];
            }
            return 1;
        }
        void del(const char *s)
        {
            if(!this->search(s))return;
            int u=0,len=strlen(s);
            for(int i=0;i<len;i++){
                int c=idx(s[i]);
                u=ch[u][c];
               // cout<<val[u]<<endl;
            }
            memset(ch[u],0,sizeof(ch[u]));
            int x=val[u];
            u=0;
            for(int i=0;i<len;i++){
                int c=idx(s[i]);
                u=ch[u][c];
                val[u]-=x;
            }
        }
    };
    char s[33],op[23];
    Trie trie;
    int main()
    {
        //freopen("f.txt","r",stdin);
        int T;
        scanf("%d",&T);
        trie.clear();
    
        while(T--){
            scanf("%s%s",op,s);
            if(op[0]=='i'){
                trie.insert(s);
            }
            else if(op[0]=='s'){
                if(trie.search(s))puts("Yes");
                else puts("No");
            }
            else{
                trie.del(s);
            }
        }
        return 0;
    }
  • 相关阅读:
    16 把第 i 个结点从链表中删除
    15 在特定结点前插入新的元素
    14 求链表的表长
    13 返回特定数据域的结点个数
    12 按号定位
    11 按值定位
    11 头插入法创建链表)
    09 尾插入法创建单链表(实现2)
    08 尾插入法创建单链表(实现1)
    centos6.5 安装gcc 4.9.0
  • 原文地址:https://www.cnblogs.com/01world/p/5651207.html
Copyright © 2020-2023  润新知