POJ 1816 Wild Words(Trie+DFS)

 

题目比较毒瘤

给出 n 个模式串,m 个单词,查询每一个单词与哪一个模式串匹配,其中 ?可以表示任意一个单词,* 可以表示为 空或者任意多个单词 

一看到这个题不应该向 AC 自动机考虑吗?

发现题目中单词的数目不多,且单词的长度很小,故在查询的时候采用暴力的方式,先利用模式串建好字典树

在查询过程中利用 dfs 的方式,但是要注意的是遇到 * 之后,由于其可以为空,所以单词的长度可以不再增加,当然也可以表示剩余的所有字母

但是这样还是不对,在 dfs 过程中不可以 return:

  • 例如样例 the ,??e*,要想保证记录答案要保证最后一个 * 被省略

这样代码就可以了

题目比较毒瘤,还要考虑重复单词,在 Discuss 中的一组样例供大家参考:

3 1
b?g*
b?g*
?ft??
bags

TLEcode: 

const int N=2e6+5;

    int n,m;
    int i,j,k;
    char s[30];
    int t[N][26],tot=0;
    vector<int> vis[N];
    vector<int> ans;

int idx(char ch)
{
    if(ch=='*') return 27;
    if(ch=='?') return 26;
    return ch-'a';
}

void insert(char *s,int id)
{
    int rt=0;
    for(int i=0;s[i];i++){
        int x=idx(s[i]);
        if(!t[rt][x]) t[rt][x]=++tot;
        rt=t[rt][x];
    }
    vis[rt].pb(id);
}

void dfs(char *s,int rt,int pos,int len)
{
    if(pos==len) if(vis[rt].size()) ans.insert(ans.end(),vis[rt].begin(),vis[rt].end());

    int x=s[pos]-'a';
    if(t[rt][x]) dfs(s,t[rt][x],pos+1,len);
    if(t[rt][26]) dfs(s,t[rt][26],pos+1,len);
    if(t[rt][27]){
        for(int i=pos;i<=len;i++){
            dfs(s,t[rt][27],i,len);
        }
    }
}

int main()
{
    //IOS;
    while(~sdd(n,m)){
        for(int i=1;i<=n;i++) ss(s),insert(s,i);
        for(int i=1;i<=m;i++){
            ss(s);
            int len=strlen(s);
            ans.clear();
            dfs(s,0,0,len);
            len=ans.size();
            if(len){
                sort(ans.begin(),ans.end());
                for(int i=0;i<len;i++) printf("%d ",ans[i]-1);
                puts("");
            }else puts("Not match");
        }
    }
    //PAUSE;
    return 0;
}

本来是打算用 vector 来解决重复的问题,可是每次都排序这样显然会 T,这里将 O(nlogn) 的排序利用桶的方式去掉一个 logn 

ACcode: 

const int N=2e6+5;

    int n,m;
    int i,j,k;
    char s[30];
    int t[N][30],tot=0;
    int vis[N],id[N];
    int mp[N];

int idx(char ch)
{
    if(ch=='*') return 27;
    if(ch=='?') return 26;
    return ch-'a';
}

int insert(char *s)
{
    int rt=0;
    for(int i=0;s[i];i++){
        int x=idx(s[i]);
        if(!t[rt][x]) t[rt][x]=++tot;
        rt=t[rt][x];
    }
    vis[rt]=1;
    return rt;
}

void dfs(char *s,int rt,int pos,int len)
{
    if(pos==len) if(vis[rt]) mp[rt]=1;

    int x=s[pos]-'a';
    if(t[rt][x]) dfs(s,t[rt][x],pos+1,len);
    if(t[rt][26]) dfs(s,t[rt][26],pos+1,len);
    if(t[rt][27]){
        for(int i=pos;i<=len;i++){
            dfs(s,t[rt][27],i,len);
        }
    }
}

void clear()
{
    for(int i=1;i<=n;i++) if(mp[id[i]]) mp[id[i]]=0;
}

int main()
{
    //IOS;
    while(~sdd(n,m)){
        for(int i=1;i<=n;i++) ss(s),id[i]=insert(s);
        for(int i=1;i<=m;i++){
            ss(s);
            int len=strlen(s);
            dfs(s,0,0,len);
            int flag=0;
            for(int j=1;j<=n;j++){
                if(mp[id[j]]){
                    if(!flag) flag=1,printf("%d",j-1);
                    else printf(" %d",j-1);
                }
            }
            if(!flag) printf("Not match");
            puts("");
            clear();
        }
    }
    PAUSE;
    return 0;
}

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页