zoukankan      html  css  js  c++  java
  • hdu1247 两棵Trie

    hdu1247 Hat’s Words
    传送门
    题意
    判断单词表中的一个单词是否为两个单词表中的两个其他单词串联的形式,输出所有这样的单词
    题解
    建立两棵Trie,一棵是正序,一棵是倒序
    遍历所有单词,设立一个标记数组,每个单词首先在正序的Trie中查找,判断每个前缀的位置是否是其他单词,在标记数组的对应下标处打上标记,之后在倒序Trie中查找,在标记数组中((n-i-2))的位置处打上标记。最后遍历标记数组,如果某个位置的值等于(2),说明这个单词这一位置的前后缀都在单词表中出现过,符合条件

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<set>
    #include<map>
    #include<cstring>
    #include<string>
    #include<sstream>
    #include<cmath>
    #include<ctime>
    #include<climits>
    #include<algorithm>
    #define LL long long
    #define PII pair<int,int>
    #define PLL pair<LL,LL>
    #define pi acos(-1.0)
    #define eps 1e-6
    #define lowbit(x) x&(-x)
    using namespace std;
    
    const int maxn=100010;
    string s[50010];
    int tot1,tot2,trie1[maxn][30],trie2[maxn][30];
    int sum[50010],len[maxn];
    bool terminal1[maxn],terminal2[maxn];
    
    void insert1(string ss,int n){
        int root=0;
        for(int i=0;i<n;i++){
            int id=ss[i]-'a';
            if(!trie1[root][id]) trie1[root][id]=++tot1;
            root=trie1[root][id];
        }
        terminal1[root]=true;
    }
    
    void insert2(string ss,int n){
        int root=0;
        for(int i=0;i<n;i++){
            int id=ss[i]-'a';
            if(!trie2[root][id]) trie2[root][id]=++tot2;
            root=trie2[root][id];
        }
        terminal2[root]=true;
    }
    
    void find1(string ss,int n){
        int root=0;
        for(int i=0;i<n-1;i++){
            int id=ss[i]-'a';
            root=trie1[root][id];
            if(terminal1[root]) sum[i]++;
        }
    }
    
    void find2(string ss,int n){
        int root=0;
        for(int i=0;i<n-1;i++){
            int id=ss[i]-'a';
            root=trie2[root][id];
            if(terminal2[root]) sum[n-i-2]++;
        }
    }
    
    int main(){
        std::ios::sync_with_stdio(false);
        int m=0;
        while(cin>>s[m]){
            len[m]=s[m].length();
            insert1(s[m],len[m]);
            reverse(s[m].begin(),s[m].end());
            insert2(s[m],len[m]);
            m++;
        }
        for(int i=0;i<m;i++){
            for(int j=0;j<len[i];j++) sum[j]=0;
            find2(s[i],len[i]);
            reverse(s[i].begin(),s[i].end());
            find1(s[i],len[i]);
            bool f=false;
            for(int j=0;j<len[i];j++){
                if(sum[j]==2){
                    f=true;
                    break;
                }
            }
            if(f) cout<<s[i]<<"
    ";
        }
        return 0;
    }
    
  • 相关阅读:
    编码转换,基础补充,深浅拷贝,id is == ,代码块(了解),小数据池(了解)
    字典(dict),字典的嵌套,集合(set)
    列表,列表的增删改查,列表的嵌套,range
    整数,布尔值,字符串,字符串详解.
    [小明学Shader]4.自定义光照----RampTexture
    [小明学Shader]3.自定义光照,半拉姆伯特
    [小明学Shader]2.理解Shader和Material的关系
    [小明学Shader]1.Diffuse
    [UGUI]你说UnityEngine.UI.Button是怎么通过拖动来增加OnClick的监听器的呢?
    [小明也得懂架构]1.架构初探
  • 原文地址:https://www.cnblogs.com/fxq1304/p/13590776.html
Copyright © 2011-2022 走看看