• POJ1816 Wild words


    传送门

    这道题能想到是trie树+搜索,不过在trie树上dfs确实让人大开眼界……

    具体怎么做呢?首先我们可以按照模式串来建立一棵trie树,不过这样的话空间限制是一个问题。解决的方法是把trie树像建图一样用链式前向星去存储,这样的话就节省了很多空间(具体怎么实现可以看代码,还是很简单的)。之后我们把这棵trie树建好,之后就得开始搜了……其实普通的点和?都很可以,不过遇到*号的话,我们就要枚举长度去向下搜索。我们记录一下当前枚举到第几位,当前的节点和当前的边,然后普通的点我们把k+1,如果遇到*的话就要枚举所有可能的长度去深搜。

    还有此题有坑……*是可以为空的,所以我们需要在搜到最后特判一下这种情况,继续搜。

    然后,这道题还有重复的模式串……解决的方法是在每个点再开一个vector来记录一下有哪些重复的串。

    看一下代码吧。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<set>
    #include<vector>
    #include<queue>
    #define pb push_back
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    
    using namespace std;
    typedef long long ll;
    const int M = 40005;
    const int N = 600005;
    const ll mod = 1000000007;
    
    int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
        if(ch == '-') op = -1;
        ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
        ans *= 10;
        ans += ch - '0';
        ch = getchar();
        }
        return ans * op;
    }
    
    struct edge
    {
        char ch;
        int next,to;
        vector<int> ed;
    }e[N];
    
    int head[N],ecnt,cnt = 1,n,m;
    char s[25];
    
    void add(int x,char c)
    {
        e[++ecnt].to = ++cnt;
        e[ecnt].ch = c;
        e[ecnt].next = head[x];
        head[x] = ecnt;
    }
    
    void insert(int k)
    {
        int u = 1,l = strlen(s);
        rep(i,0,l-1)
        {
        int v = -1;
        char c = s[i];
        for(int j = head[u];j;j = e[j].next)
        {
            if(e[j].ch == c)
            {
            v = e[j].to;
            if(i == l-1) e[j].ed.pb(k);
            break;
            }
        }
        if(v < 0)
        {
            add(u,c),v = cnt;
            if(i == l-1) e[ecnt].ed.pb(k);
        }
        u = v;
        }
    }
    
    vector <int> ans;
    int len;
    
    void check(int u,int k,int p)
    {
        if(k == len)
        {
        if(!e[p].ed.empty()) rep(i,0,e[p].ed.size()-1) ans.pb(e[p].ed[i]);
        for(int j = head[u];j;j = e[j].next) if(e[j].ch == '*') check(e[j].to,k,j);
        return;
        }
        char c = s[k];
        for(int j = head[u];j;j = e[j].next)
        {
        if(e[j].ch == c || e[j].ch == '?') check(e[j].to,k+1,j);
        if(e[j].ch == '*') rep(q,0,len-k) check(e[j].to,k+q,j);
        }
    }
    
    bool vis[100001];
    
    int main()
    {
        n = read(),m = read();
        rep(i,0,n-1) scanf("%s",s),insert(i);
        rep(j,0,m-1)
        {
        scanf("%s",s),ans.clear(),len = strlen(s);
        check(1,0,0);
        if(ans.empty()) printf("Not match
    ");
        else
        {
            memset(vis,0,sizeof(vis));
            sort(ans.begin(),ans.end());
            rep(i,0,ans.size()-1) if(!vis[ans[i]]) printf("%d ",ans[i]),vis[ans[i]] = 1;
            enter;
        }
        }
        return 0;
    }
  • 相关阅读:
    转发-》c++ stl multimap基本操作使用技巧详细介绍
    控件传递,待更新
    封装函数获取体的最大4个角
    找vector最大最小《转载》
    获取面面积,资料来自录制和网友分享
    【转】插入排序
    NXOpen获取UFUN的tag
    创建注释
    创建铜公开粗程序
    NXopen create chamfer tool
  • 原文地址:https://www.cnblogs.com/captain1/p/9770041.html
Copyright © 2020-2023  润新知