zoukankan      html  css  js  c++  java
  • SPOJ Hacking(字典树 + 搜索)题解

    思路1:字典树存每个串,然后dfs遍历是否存在。这里有个技巧,如果每次都重新初始化字典树为-1,那么会超时,所以我先初始化为-1,然后设一个Case,每个test时Case都++,那么只要开一个数组判断是否等于Case,如果等于就说明有这条路,不等则没有。这道题用字典树做要注意剪枝。

    思路2:这道题能随机看命过

    代码1:

    #include<queue>
    #include<cstring>
    #include<set>
    #include<map>
    #include<stack>
    #include<cmath>
    #include<vector>
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    typedef long long ll;
    const int maxn = 1e4 + 10;
    const int seed = 131;
    const ll MOD = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    int n, m, k, length, Case;
    char s[maxn], ans[150];
    int trie[maxn * 100][27], cs[maxn * 100][27], tot;
    void update(int st){
        int p = 0;
        for(int i = 0; i < m; i++){
            if(st + i > n) return;
            int v = s[st + i] - 'a';
            if(v >= k) return;    //剪枝
            if(cs[p][v] != Case){
                trie[p][v] = ++tot;
                cs[p][v] = Case;
            }
            p = trie[p][v];
        }
    }
    bool dfs(int p, int len){
        if(len > m) return false;
        for(int i = 0; i < k; i++){
            if(cs[p][i] != Case){
                ans[length++] = 'a' + i;
                return true;
            }
            else if(dfs(trie[p][i], len + 1)){
                ans[length++] = 'a' + i;
                return true;
            }
        }
        return false;
    }
    int main(){
        int t;
        Case = 0;
        memset(cs, -1, sizeof(cs));
        scanf("%d", &t);
        while(t--){
            Case++;
            tot = 0;
            scanf("%d%d%d", &n ,&m, &k);
            scanf("%s", s + 1);
            for(int i = 1; i <= n; i++){
                update(i);
            }
            length = 0;
            dfs(0, 1);
            for(int i = length - 1; i >= 0; i--)
                printf("%c", ans[i]);
            printf("
    ");
        }
        return 0;
    }

    代码2:

    #include<queue>
    #include<cstring>
    #include<set>
    #include<map>
    #include<stack>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    typedef long long ll;
    const int maxn = 1e4 + 10;
    const int seed = 131;
    const ll MOD = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    int n, m, k;
    char s[maxn];
    int main(){
        int t;
        srand(time(NULL));
        scanf("%d", &t);
        while(t--){
            map<string, int> st;
            scanf("%d%d%d", &n ,&m, &k);
            scanf("%s", s + 1);
            for(int i = 1; i <= n - m + 1; i++){
                string ss;
                for(int j = i; j < i + m; j++){
                    ss += s[j];
                }
                st[ss] = 1;
            }
            string ans;
            while(true){
                ans = "";
                for(int i = 0; i < m; i++){
                    ans += 'a' + rand() % k;
                }
                if(st[ans] == 0){
                    cout << ans << endl;
                    break;
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    [MCM] PSO粒子群算法解决TSP问题
    [MCM] 2017研究生数学建模竞赛A题 3架飞机 TSP 求总路径最小
    [tool] AI视频翻译 解决英文视频字幕问题(类似youtube自动生成字幕)
    使用vsnprintf后链接错误及解决方法
    Linux Shell编程
    如何把va_list可变参数传送到下一级函数中(如传送到printf)
    ubuntu phone/touch的源码从哪里下载?
    The Native POSIX Thread Library for Linux
    Linux内核头文件与内核与库的关系
    Buildroot阅读笔记
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9636079.html
Copyright © 2011-2022 走看看