BZOJ1819 [JSOI]Word Query电子字典 Trie

欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解


题目传送门 - BZOJ1819


题意概括

  字符串a与字符串b的编辑距离是指:允许对a或b串进行下列“编辑”操作,将a变为b或b变为a,最少“编辑”次数即为距离。

  删除串中某个位置的字母;

  添加一个字母到串中某个位置;

  替换串中某一位置的一个字母为另一个字母;

  对于一个待查询字符串,如果它是单词,则返回-1;如果它不是单词,则返回字典中有多少个单词与它的编辑距离为1。


题解

  根据输入的单词构建trie,然后大力搜索即可。

  dfs,时间复杂度为m*20*20*20可以过去


 

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
const int N=10005,L=20+5;
struct Trie{
    int e,Next[26];
    void init(){
        e=0;
        memset(Next,0,sizeof Next);
    }
}tree[N*L];
int n,m,ans,trie_cnt,len,addv[N],mark;
char ch[L];
void build(char ch[],int bh){
    int rt=1,t,len=strlen(ch);
    for (int i=0;i<len;i++){
        t=ch[i]-'a';
        if (!tree[rt].Next[t])
            tree[tree[rt].Next[t]=++trie_cnt].init();
        rt=tree[rt].Next[t];
    }
    tree[rt].e=bh;
}
void init_trie(){
    tree[1].init();
    trie_cnt=1;
}
bool dfs(int pos,int rt,bool used){
    if (pos>=len){
        if (!used)
            for (int i=0;i<26;i++)
                if (tree[rt].Next[i])
                    if (dfs(pos,tree[rt].Next[i],1))
                        return 1;
        if (tree[rt].e==0)
            return 0;
        if (!used)
            return 1;
        if (addv[tree[rt].e]!=mark)
            ans++;
        addv[tree[rt].e]=mark;
        return 0;
    }
    int t=ch[pos]-'a';
    if (used){
        if (!tree[rt].Next[t])
            return 0;
        return dfs(pos+1,tree[rt].Next[t],1);
    }
    //not used
    if (tree[rt].Next[t])
        if (dfs(pos+1,tree[rt].Next[t],0))
            return 1;
    //add & change
    for (int i=0;i<26;i++)
        if (tree[rt].Next[i]){
            int nxt=tree[rt].Next[i];
            if (dfs(pos,nxt,1))
                return 1;
            if (t!=i)
                if (dfs(pos+1,nxt,1))
                    return 1;
        }
    // delete
    if (dfs(pos+1,rt,1))
        return 1;
    return 0;
}
int main(){
    scanf("%d%d",&n,&m);
    init_trie();
    for (int i=1;i<=n;i++){
        scanf("%s",ch);
        build(ch,i);
    }
    memset(addv,0,sizeof addv);
    for (int i=1;i<=m;i++){
        mark=i;
        scanf("%s",ch);
        len=strlen(ch);
        ans=0;
        if (dfs(0,1,0)){
            puts("-1");
            continue;
        }
        printf("%d\n",ans);
    }
    return 0;
}

  

posted @   zzd233  阅读(513)  评论(0编辑  收藏  举报

点击右上角即可分享
微信分享提示