zoukankan      html  css  js  c++  java
  • POJ1816:Wild Words——题解

    http://poj.org/problem?id=1816

    比较麻烦的trie。

    首先你需要选择针对n还是m建立trie,这里我选择了针对n。

    那么就需要面临卡空间的问题。

    这里提供了一种链式前向星的方法能够当你不会指针trie的时候卡过空间。(做法看代码吧)

    然后针对m进行在trie上的dfs即可。

    对于相同字符或?来说,trie下移1位,匹配串移动1位。

    对于*来说,trie下移,匹配串移动0~长度位。

    (合计这道题就难在模拟上了)

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    using namespace std;
    const int maxn=600001;
    char s[21];
    struct node{
        char se;
        int to;
        int nxt;
        vector<int>ed;
    }edge[maxn];
    int head[maxn],cnt=0,cnt1=1;
    void add(int u,char c){
        cnt++;cnt1++;
        edge[cnt].se=c;
        edge[cnt].to=cnt1;
        edge[cnt].nxt=head[u];
        head[u]=cnt;
        return;
    }
    void insert(int k){
        int u=1;
        int l=strlen(s);
        for(int i=0;i<l;i++){
        int v=-1;
        char c=s[i];
        for(int j=head[u];j;j=edge[j].nxt){
            if(edge[j].se==c){
            v=edge[j].to;
            if(i==l-1)edge[j].ed.push_back(k);
            break;
            }
        }
        if(v<0){
            add(u,c);
            v=cnt1;
            if(i==l-1)edge[cnt].ed.push_back(k);
        }
        u=v;
        }
        return;
    }
    vector<int>ans;
    int l;
    void check(int u,int k,int p){
        if(k==l){
        if(!edge[p].ed.empty()){
            for(int i=0;i<edge[p].ed.size();i++){
            ans.push_back(edge[p].ed[i]);
            }
        }
        for(int j=head[u];j;j=edge[j].nxt){
            int v=edge[j].to;
            if(edge[j].se=='*'){
            check(v,k,j);
            }
        }
        return;
        }
        char c=s[k];
        for(int j=head[u];j;j=edge[j].nxt){
        int v=edge[j].to;
        if(edge[j].se==c||edge[j].se=='?'){
            check(v,k+1,j);
        }
        if(edge[j].se=='*'){
            for(int q=0;q<=l-k;q++){
            check(v,k+q,j);
            }
        }
        }
        return;
    }
    bool t[100001];
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++){
        scanf("%s",s);
        insert(i);
        }
        for(int j=0;j<m;j++){
        scanf("%s",s);
        ans.clear();
        l=strlen(s);
        check(1,0,0);
        if(ans.empty()){
            printf("Not match");
        }else{
            memset(t,0,sizeof(t));
            sort(ans.begin(),ans.end());
            for(int i=0;i<ans.size();i++){
            if(!t[ans[i]]){
                printf("%d ",ans[i]);
                t[ans[i]]=1;
            }
            }
        }
        printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    文本域光标操作(选、添、删、取)的jQuery扩展
    jQuery插件,将内容插入到光标处
    onmouseout,mouseover经过子元素也触发的问题解决方案
    【M4】非必要不提供default 构造方法
    【M3】绝对不要以多态方式处理数组
    100亿个数字找出最大的10个
    【M2】最好使用C++转型操作符
    【M26】限制某个class所能产生的对象数量
    理解extern
    变量的属性
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/7859317.html
Copyright © 2011-2022 走看看