• TOJ3097: 单词后缀 (字典树 or map瞎搞)


    传送门 (<---可以点击的~)

    时间限制(普通/Java):1000MS/3000MS     内存限制:65536KByte

    描述

    有些英语单词后缀都是一样的,现在我们需要从给定的一堆单词里面找出某个后缀的单词个数。

    输入

    输入有多组数据。
    每组第一行输入n,m,0<=n,m<=100000,
    第二行到n+1行:输入单词,每个单词仅有小写英文字母组成,长度不超过10。
    第n+2行到n+m+1行,输入要找的单词后缀。

    输出

    在n个单词里面找出输入单词后缀的单词个数,然后输出。每个数据与数据之间换行。

    样例输入

    6 3
    someone
    everyone
    outside
    inside
    somebody
    nobody
    one
    side
    body

    样例输出

    2
    2
    2

    思路:既然是求后缀个数,把字符串倒一倒就变求前缀个数了,然后就是写字典树。这题的话,map瞎搞也是能过的,耗时在800MS左右(感觉还是老老实实字典树吧~)

        拿来练字典树模板的。

    字典树代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    char str[10100];
    struct note{
        note* nxt[27];
        int sum;//保存出现个数 
        note(){
            sum = 0;
            memset(nxt,0,sizeof(nxt));
        }
    }a[200010];
    void insert(note *root,char s[]){
        note *p = root;
        int i = 0;
        while(s[i]){
            int j = s[i++] - 'a';
            if(p->nxt[j] ==NULL){
                p->nxt[j] = new note();    
            }
            p = p->nxt[j];
            (p->sum) ++;//在构建的时候直接把当前结点的sum+1 说明出现过后缀 
        }
    }
    int search(note *root ,char s[]){
        note *p = root;
        int i = 0;
        while(s[i]){
            int j = s[i++]-'a';
            if(p->nxt[j] == NULL)return 0;
            p = p -> nxt[j];
        }
        return p -> sum;
    }
    int main(){
        int n,m;
        while(~scanf("%d %d",&n,&m)){
            note * root = new note();
            while(n--){
                scanf("%s",str);
                strrev(str);
                insert(root,str); 
            }
            while(m--){
                scanf("%s",str);
                strrev(str);
                printf("%d
    ",search(root,str));
            }
        }
        return 0; 
    }

    map代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<stack>
    #include<vector>
    #include<map>
    #include<queue>
    #include <sstream>
    #define LL long long
    using namespace std;
    map<string,int>ma;
    int main(){
        int n,m;
        string s;
        char str[1010];
        while(~scanf("%d%d",&n,&m)){
            ma.clear();
            while(n--){
                cin>>s;
                reverse(s.begin(),s.end());
                while(s.size()>0){
                    ma[s]++;
                    s.erase(s.size()-1);
                }
            } 
            while(m--){
                scanf("%s",str);strrev(str);
                printf("%d
    ",ma[str]);
            }
        }
    }
  • 相关阅读:
    hdu 3790 最短路径问题
    hdu 2112 HDU Today
    最短路问题 以hdu1874为例
    hdu 1690 Bus System Floyd
    hdu 2066 一个人的旅行
    hdu 2680 Choose the best route
    hdu 1596 find the safest road
    hdu 1869 六度分离
    hdu 3339 In Action
    序列化和反序列化
  • 原文地址:https://www.cnblogs.com/Esquecer/p/8669106.html
Copyright © 2020-2023  润新知