zoukankan      html  css  js  c++  java
  • UVA

    1、给一个串,在给一个单词集合,求用这个单词集合组成串,共有多少种组法。

    例如:串 abcd, 单词集合 a, b, cd, ab

    组合方式:2种:

    a,b,cd

    ab,cd

    2、把单词集合建立字典树,然后从后向前dp,dp[i]=dp[i]+dp[i+len(x)]; 其中x为当前找到的前缀长度。

    3、

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    
    #define MAX 26
    #define MOD 20071027
    
    int dp[300005];
    
    struct Trie
    {
        Trie *next[MAX];
        int v;   //根据需要变化,1代表无此单词,-1代表有此单词
    };
    Trie *root;
    
    void createTrie(char *str)
    {
        int len = strlen(str);
        Trie *p = root, *q;
        for(int i=0; i<len; ++i)
        {
            int id = str[i]-'a';
            if(p->next[id] == NULL)
            {
                // q = (Trie *)malloc(sizeof(Trie));
                q = new Trie;
                q->v = 1;    //初始v==1
                for(int j=0; j<MAX; ++j)
                    q->next[j] = NULL;
                p->next[id] = q;
            }
            p = p->next[id];
        }
        p->v = -1;   //若为结尾,则将v改成-1表示
    }
    int findTrie(char *str,int mI,int len)
    {
        int ret=0;
        //int len = strlen(str);//每次都计算,很浪费时间
        Trie *p = root;
        for(int i=mI; i<len; ++i)
        {
            int id = str[i]-'a';
            p = p->next[id];
            if(p == NULL)   //若为空集,表示不存以此为前缀的串
                return ret;
            if(p->v == -1){   //字符集中已有串是此串的前缀
                ret=(ret+dp[i+1])%MOD;
            }
        }
        return ret;
    }
    int deleteTrie(Trie* T)
    {
        int i;
        if(T==NULL)
            return 0;
        for(i=0; i<MAX; i++)
        {
            if(T->next[i]!=NULL)
                deleteTrie(T->next[i]);
        }
        //free(T);
        delete(T);
        return 0;
    }
    int main()
    {
        char str[300005];
        char str2[105];
        int i,S,len,mCase=0;
        while(~scanf("%s",str)){
            root=new Trie;
            for(i=0; i<MAX; i++)
                root->next[i]=NULL;
            memset(dp,0,sizeof(dp));
            len=strlen(str);
            scanf("%d",&S);
            while(S--){
                scanf("%s",str2);
                createTrie(str2);
            }
    
            dp[len]=1;
            for(i=len-1;i>=0;--i)
                dp[i]=findTrie(str,i,len);
    
            printf("Case %d: %d
    ",++mCase,dp[0]);
            delete(root);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    bzoj3884: 上帝与集合的正确用法(数论)
    洛谷10月月赛R2·浴谷八连测R3题解
    bzoj5055: 膜法师(BIT)
    bzoj2213: [Poi2011]Difference(思维题)
    bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)
    一模 (2) day2
    一模 (2) day1
    Prime Palindromes
    常州培训 day5 解题报告
    一模 (1) day2
  • 原文地址:https://www.cnblogs.com/gongpixin/p/4945896.html
Copyright © 2011-2022 走看看