zoukankan      html  css  js  c++  java
  • LA 3942 Remember the Word

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1943

    本题练习前缀树(Trie),又称字典树。

    Trie结构体模板:

    struct Trie
    {
        int sz;
        int ch[maxnode][sigma_size];
        int val[maxnode];
        void init()
        {
            sz = 1;
            memset(ch[0],0,sizeof(ch[0]));
        }
        int idx(char c)
        {
            return c - 'a';
        }
        void insert(char *s,int v)
        {
            int u = 0;
            int 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] = 0;//注意这里不要写错
                    ch[u][c] = sz++;
                }
                u = ch[u][c];
            }
            val[u] = v;
        }
        int find(char *s)
        {
            int u = 0;
            int n = strlen(s);
            for(int i=0;i<n;i++)
            {
                int c = idx(s[i]);
                if(!ch[u][c]) return 0;
                u = ch[u][c];
            }
            return val[u];
        }
    };


    对于本题而言,DP+Trie可以解决。

    其中,d[i]代表以s[i-1]结尾的分解方案。

    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <stdlib.h>
    #include <time.h>
    #include <vector>
    #include <set>
    #include <map>
    #include <algorithm>
    
    using namespace std;
    
    #define maxnode 4010*100
    #define sigma_size 26
    #define MOD 20071027
    
    struct Trie
    {
        int sz;
        int ch[maxnode][sigma_size];
        int val[maxnode];
        void init()
        {
            sz = 1;
            memset(ch[0],0,sizeof(ch[0]));
        }
        int idx(char c)
        {
            return c - 'a';
        }
        void insert(char *s,int v)
        {
            int u = 0;
            int 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] = 0;//注意这里不要写错
                    ch[u][c] = sz++;
                }
                u = ch[u][c];
            }
            val[u] = v;
        }
        int find(char *s)
        {
            int u = 0;
            int n = strlen(s);
            for(int i=0;i<n;i++)
            {
                int c = idx(s[i]);
                if(!ch[u][c]) return 0;
                u = ch[u][c];
            }
            return val[u];
        }
    };
    Trie trie;
    char s[300005];
    int d[300005];//d[i]代表以s[i-1]结尾的分解方案
    
    int main()
    {
    
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
        int n;
        char temp[105];
        int cas = 0;
        while(scanf(" %s",s)!=EOF)
        {
            cas++;
            memset(d,0,sizeof(d));
            d[0] = 1;
            trie.init();
            scanf(" %d",&n);
            for(int i=0;i<n;i++)
            {
                scanf(" %s",temp);
                trie.insert(temp,1);
            }
            int len = strlen(s);
            for(int i=0;i<len;i++)
            {
                int u = 0;
                for(int j=i+1;j<=len;j++)
                {
                    int c = trie.idx(s[j-1]);
                    if(!trie.ch[u][c]) break;
                    if(trie.val[trie.ch[u][c]])
                    {
                        d[j] += d[i];
                        if(d[j]>=MOD) d[j] -= MOD;
                    }
                    u = trie.ch[u][c];
                }
            }
            printf("Case %d: %d\n",cas,d[len]);
        }
    }
    



  • 相关阅读:
    监听
    用户管理
    oracle网络
    实例 参数
    存储管理
    oracle 体系
    实例
    修改
    集合操作
    17.08.18
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3073071.html
Copyright © 2011-2022 走看看