zoukankan      html  css  js  c++  java
  • 1401

    注意到单词的长度最长100,其实最糟糕复杂度应该能到O(300005*100),需要注意的是在字典树上匹配单词时,一旦不匹配,则后面的就不会匹配,需要break出来(这个害我TLE查了半天,日!),还有,要注意strlen的时候,那个api的复杂度貌似是O(n)的,题目中提到输入数据的不同的test case之间有一个blank line,我理解成输出不同case之间要回车,OJ居然没判成PE,而是判成WA,这两天题写的真蛋疼(吐槽下)。

    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <stack>
    #include <iostream>
    using namespace std;
    
    const int MAXN =  300005;
    const int M = 20071027;
    
    typedef long long int64;
    
    char ch[MAXN];
    int64 dp[MAXN];
    
    int id[4005 * 105][26], cnt;
    bool flag[4005 * 105];
    
    
    class DicNode {
    public:
        bool flag;
        DicNode *sons[26];
        DicNode() {
            flag = false;
            memset(sons, NULL, sizeof(sons));
        }
    };
    
    class DicTree2 {
    public:
        DicTree2() {
            cnt = 1;
            memset(id, -1, sizeof(id));
            memset(flag, false, sizeof(flag));
        }
        ~DicTree2() {
        
        }
        void insert(const char *s) {
            int len = strlen(s);
            int node = 0;
            for (int i = 0; i < len; i++) {
                if (id[node][s[i] - 'a'] == -1) {
                    id[node][s[i] - 'a'] = cnt++;
                } 
                node = id[node][s[i] - 'a'];
                if (i == len - 1) {
                    flag[node] = true;
                }
            }
        }
        bool query(const char *s) {
            int len = strlen(s);
            int node = 0;
            for (int i = 0; i < len; i++) {
                if (id[node][s[i] - 'a'] == -1) {
                    return false;
                } 
                node = id[node][s[i] - 'a'];
            }
            return flag[node];
        }
        int64 f(int b, int len) {
            if (dp[b] != -1) return dp[b];
            dp[b] = 0;
            if (b == len) return dp[b] = 1;
            int node = 0;
            for (int i = b; i < len; i++) {
                if (id[node][ch[i] - 'a'] != -1) {
                    node = id[node][ch[i] - 'a'];
                    if (flag[node]) dp[b] = (dp[b] + f(i + 1, len)) % M;
                } else {
                    break;
                }
            }
            return dp[b];
        }
    };
    
    class DicTree {
    public:
        DicNode *root;
        DicTree() {
            root = new DicNode();
        }
        ~DicTree() {
            if (NULL != root) {
                free(root);
            }
        }
        void free(DicNode *node) {
            for (int i = 0; i < 26; i++) {
                if (node->sons[i] != NULL) {
                    free(node->sons[i]);
                }
            }
            delete node;
        }
        void insert(const char *s) {
            int len = strlen(s);
            DicNode *node = root;
            for (int i = 0; i < len; i++) {
                if (node->sons[s[i] - 'a'] == NULL) {
                    node->sons[s[i] - 'a'] = new DicNode();
                } 
                node = node->sons[s[i] - 'a'];
                if (i == len - 1) {
                    node->flag = true;
                }
            }
        }
        bool query(const char *s) {
            int len = strlen(s);
            DicNode *node = root;
            for (int i = 0; i < len; i++) {
                if (node->sons[s[i] - 'a'] == NULL) {
                    return false;
                }
                node = node->sons[s[i] - 'a'];
            }
            return node->flag;
        }
        int64 f(int b, int len) {
            if (dp[b] != -1) return dp[b];
            dp[b] = 0;
            if (b == len) return dp[b] = 1;
            DicNode *node = root;
            for (int i = b; i < len; i++) {
                if (node->sons[ch[i] - 'a'] != NULL) {
                    node = node->sons[ch[i] - 'a']; 
                    if (node->flag) dp[b] = (dp[b] + f(i + 1, len)) % M; 
                } else {
                    break;
                } 
            }
            return dp[b];
        }
    };
    
    
    
    int main() {
        int c = 0;
        while (scanf("%s", ch) != EOF) {
            int s;
            scanf("%d", &s);
            DicTree dic;
            for (int i = 0; i < s; i++) {
                char str[105];
                scanf("%s", str);
                dic.insert(str);
            }
            memset(dp, -1, sizeof(dp));
            printf("Case %d: %lld
    ", ++c, dic.f(0, strlen(ch)));
        }
    }
  • 相关阅读:
    国内开源缺陷管理系统PPM Bug v1.0发布
    LUA、python、注册表和正则表达式简述
    精通Windows API 线程同步控制源码
    博士生传给硕士生的经验 (转载)这实在是一篇少走许多学习弯路的好文章
    得到任务管理器的正在执行的程序列表 系统的临时路径及临时文件绝对路径
    创建设一个开机自动运行的计划任务,并且命名和当前登陆用户名相关
    刚踏实入IT行业几个月感悟
    给IT新人的15点建议:苦逼程序员的辛酸反省与总结
    char转换成WCHAR简单方法
    字符操作、文件操作和CMD命令的使用——c/c++编
  • 原文地址:https://www.cnblogs.com/litstrong/p/3302784.html
Copyright © 2011-2022 走看看