Codeforces 514C. Watto and Mechanism解题报告(字典树)

时间:2022-12-30 13:12:30

传送门
题意:给你一个字典和一些询问,问你对于每个询问的字符串必须更改一个字符,能否得到字典中的某一个单词。
思路:先构造一颗字典树,然后搜一遍就行了,要注意strlen不能每次都用,常数很大!

#include<bits/stdc++.h>
#define rep(i,k,n) for(int i=k;i<=n;i++)
using namespace std;
const int maxn=300005,maxm=600005;
int tree[maxm][5],en[maxm];
int n,m,e;
char s[maxm];
bool flag;
bool siz[maxm];
int lenth;
void add_edge(char c[])
{
    int len=(int)strlen(c);
    int root=0;
    rep(i,0,len-1)
    {
        if(!tree[root][c[i]-'a'])
        tree[root][c[i]-'a']=++e;
        root=tree[root][c[i]-'a'];
    }
    en[root]=1;
    siz[(int)strlen(c)]=1;
}
void dfs(int root,int x,int pos,int cn)
{
    if(flag)return;
    //cout<<char(x+'a')<<" "<<pos<<endl;
    if(pos>=lenth)
    {
        return;
    }
    int cnn=cn;
    if(pos==lenth-1 && en[root])
    {
        //cout<<char(x+'a')<<"   "<<pos<<endl;
        if((x==s[pos]-'a' && cnn==1) || (x!=s[pos]-'a' && cnn==0))
        flag=1;
        return;
    }
    if(pos!=-1)
    {
        if(s[pos]-'a'!=x)
        {
            cnn++;
            if(cnn>=2)
            return;
        }
    }
    int i=0;
    if(tree[root][i] && (cnn==0 || (cnn==1 && s[pos+1]-'a'==i)))
        {
            dfs(tree[root][i],i,pos+1,cnn);
            if(flag)
            return;
        }
        i=1;
        if(tree[root][i]  && (cnn==0 || (cnn==1 && s[pos+1]-'a'==i)))
        {
            dfs(tree[root][i],i,pos+1,cnn);
            if(flag)
            return;
        }
        i=2;
        if(tree[root][i] && (cnn==0 || (cnn==1 && s[pos+1]-'a'==i)))
        {
            dfs(tree[root][i],i,pos+1,cnn);
            if(flag)
            return;
        }
}
int main()
{
    scanf("%d%d",&n,&m);
    if(n==1 && m==1)
    {
        string s1,s2;
        cin>>s1>>s2;
        if(s1.size()!=s2.size())
        {
            puts("NO");
            return 0;
        }
        int cnt=0;
        rep(i,0,s1.size()-1)
        {
            if(s1[i]!=s2[i])
            {
                cnt++;
            }
            if(cnt>=2)
            {
                flag=1;
                break;
            }
        }
        if(flag || cnt==0) puts("NO");
        else puts("YES");
        return 0;
    }
    rep(i,1,n)
    {
        char c[maxm];
        scanf("%s",c);
        add_edge(c);
    }
    //cout<<en[0]<<endl;
    rep(i,1,m)
    {
        scanf("%s",s);
        lenth=(int)strlen(s);
        flag=0;
        if(siz[lenth]==0)
        {
            puts("NO");
            continue;
        }
        dfs(0,0,-1,0);
        if(flag) puts("YES");
        else puts("NO");
    }
    return 0;
}