zoukankan      html  css  js  c++  java
  • E

    E - Petya and Exam

     CodeForces - 832B 

    这个题目其实可以不用字典树写,但是因为之前写过poj的一个题目,意思和这个差不多,所以就用字典树写了一遍。

    代码还是很好理解的,主要就是哪个findx函数,这个要好好理解。

    如果碰到*或着?就要重新标记一下,其他都是一样的,对于?可以跳过好字母,对于*可以跳过若干个不好的字母,

    这个就在直接跳过之前加一个判断条件就可以了。

    贴一下代码

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<map>
    #include<iomanip>
    #define INF 99999999
    using namespace std;
    const int maxn = 1e5 + 10;
    typedef long long ll;
    int tree[maxn][30], tot = 0, ans, isgood[1000];
    bool flag[maxn];
    char good[30], s[maxn], str[maxn];
    int add(char *s) {
        int root = 0, id, len = strlen(s);
        for (int i = 0; i < len; i++) {
            if (s[i] == '*') id = 26;
            else if (s[i] == '?') id = 27;
            else id = s[i] - 'a';
            if (!tree[root][id]) tree[root][id] = ++tot;
            root = tree[root][id];
            // printf("root=%d s=%c
    ", root, s[i]);
        }
        flag[root] = true;
        return root;
    }
    
    void findx(char *s, int root, int pos) {
        // printf("%s root=%d pos=%d
    ", s, root, pos);
        int len = strlen(s);
        if (pos > len) return;
        if (len == pos && flag[root]) {
            ans = 1;
            return;
        }
        if (tree[root][26]) {
            int flag = 1;
            int len1 = strlen(str) - 1;
            int ends = len1 - pos;
            // printf("ends=%d len-ends=%d pos=%d
    ", ends, len - ends-1, pos);
            for (int i = pos; i <= len - ends - 1; i++) {
                int id = s[i] - 'a';
                if (isgood[id]) {
                    flag = 0;
                    break;
                }
            }
            // printf("flag=%d pos=%d len-ends=%d
    ", flag, pos, len - ends);
            if (flag&&len - ends >= pos) findx(s, tree[root][26], len - ends);
            // for (int j = pos; j <= len; j++) {
            //     int id = s[j] - 'a';
            //     if (isgood[id]) break;
            //     findx(s, tree[root][26], j + 1);
            // }
        }
        if (tree[root][27]) {
            int length = strlen(good);
            for (int i = 0; i < length; i++) {
                if (s[pos] == good[i]) findx(s, tree[root][27], pos + 1);
            }
        }
        int id = s[pos] - 'a';
        if (s[pos] <= 'z'&&s[pos] >= 'a'&&tree[root][id]) findx(s, tree[root][id], pos + 1);
    }
    
    int main() {
        scanf("%s%s", good, str);
        int len = strlen(good);
        for (int i = 0; i < len; i++) {
            int id = good[i] - 'a';
            isgood[id] = 1;
        }
        int num = add(str);
        int m;
        scanf("%d", &m);
        while (m--) {
            scanf("%s", s);
            ans = 0;
            findx(s, 0, 0);
            if (ans) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
    字典树

    Wild Words poj 1816

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<map>
    #include<iomanip>
    #define INF 99999999
    using namespace std;
    const int maxn = 2e6 + 10;
    typedef long long ll;
    int tree[maxn][30], tot = 0, ans, p[maxn];
    bool flag[maxn], vis[maxn];
    char s[maxn], str[maxn];
    int add(char *s) {
        int root = 0, id, len = strlen(s);
        for (int i = 0; i < len; i++) {
            if (s[i] == '*') id = 26;
            else if (s[i] == '?') id = 27;
            else id = s[i] - 'a';
            if (!tree[root][id]) tree[root][id] = ++tot;
            root = tree[root][id];
        }
        flag[root] = true;
        return root;
    }
    
    void findx(char *s, int root, int pos) {
        // printf("%s root=%d pos=%d
    ", s, root, pos);
        int len = strlen(s);
        if (pos > len) return;
        if (len == pos && flag[root]) {
            vis[root] = 1;
        }
        if (tree[root][26]) {
            for (int i = pos; i <= len; i++) findx(s, tree[root][26], i);
        }
        if (tree[root][27])    findx(s, tree[root][27], pos + 1);
        int id = s[pos] - 'a';
        if (s[pos] <= 'z'&&s[pos] >= 'a'&&tree[root][id]) findx(s, tree[root][id], pos + 1);
    }
    vector<int>res;
    int main() {
        int n, m;
        scanf("%d%d", &n, &m);
        for(int i=1;i<=n;i++)
        {
            scanf("%s", str);
            p[i]=add(str);
        }
        while(m--)
        {
            scanf("%s", str);
            findx(str, 0, 0);
            res.clear();
            for(int i=1;i<=n;i++) if (vis[p[i]]) res.push_back(i - 1);
            int len = res.size();
            if (len == 0) printf("Not match
    ");
            else {
                for (int i = 0; i < len - 1; i++) printf("%d ", res[i]);
                printf("%d
    ", res[len - 1]);
            }
            for (int i = 1; i <= n; i++) vis[p[i]] = 0;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    请简单说一下你了解的端口及对应的服务?
    地址解析协议ARP和逆地址解析协议RARP
    IP地址分类
    OSI分层和五层协议
    对象如何晋升到老年代?
    JVM 垃圾回收机制,何时触发 MinorGC 等操作
    什么是引用?
    类加载机制
    Solaris10怎么创建flash archive
    RPC: program not registered (ZT)
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/11370497.html
Copyright © 2011-2022 走看看