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;
    }
    
  • 相关阅读:
    几个ssh和sftp的命令
    发现一个github的奇葩设定
    插耳机对orientation sensor的影响
    android中MediaPlayer类的用法
    Oracle 高性能SQL引擎剖析----执行计划
    【转】对列式数据库的一点总结和展望
    【转】大数据分析(Big Data OLAP)引擎Dremel, Tenzing 以及Impala
    TCP/IP协议详解---概述
    读取HttpWebResponse流的两种方法及注意的问题
    This project references NuGet package(s) that are missing on this computer.
  • 原文地址:https://www.cnblogs.com/fxq1304/p/13590776.html
Copyright © 2011-2022 走看看