Codeforces 514C Watto and Mechanism 【Trie树】+【DFS】

<题目链接>

题目大意:
输入n个单词构成单词库,然后进行m次查询,每次查询输入一个单词(注意这些单词只由a,b,c构成),问该单词库中是否存在与当前查询的单词有且仅有一个字符不同的单词。

解题分析:
本题将单词库中所有的单词先建trie树,然后进行容错数为1的字符串匹配,主要是在trie树上跑DFS,具体步骤见代码:

 

#include <bits/stdc++.h>
using namespace std;

const int N = 6e5+5;
int n,m,pos,nxt[N*3][3],num[N*3];
char s[N];

void Insert(char *s){
    int now=0;
    for(int i=0;s[i];i++){
        int to=s[i]-'a';
        if(!nxt[now][to])nxt[now][to]=++pos;
        now=nxt[now][to];
    }
    num[now]=1;
}
bool query(int now,int lc,int cur){        
    if(s[lc]=='\0'){            //搜到字符串末尾
        if(cur==0 && num[now]==1)return true;        //恰好有一处不同
        else return false;
    }
    int to=s[lc]-'a';    
    if(nxt[now][to]){            //自然匹配
        if(query(nxt[now][to],lc+1,cur))return true;
    }
    if(cur==1){                    //同时搜一下如果恰好不同的地方是这一位的情况
        for(int i=0;i<3;i++){
            int to=i;
            if(to==s[lc]-'a' || !nxt[now][to])continue;            //跳过与当前位相同和不存在的情况
            if(query(nxt[now][to],lc+1,0))return true;
        }
    }
    return false;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%s",s);
        Insert(s);
    }
    while(m--){
        scanf("%s",s);
        if(query(0,0,1))puts("YES");
        else puts("NO");
    }
}

 

posted @ 2018-11-01 20:19  悠悠呦~  阅读(160)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end