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

传送门
题意:给你一个字典和一些询问,问你对于每个询问的字符串必须更改一个字符,能否得到字典中的某一个单词。
思路:先构造一颗字典树,然后搜一遍就行了,要注意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;
}

原文地址:https://www.cnblogs.com/NightRaven/p/9739756.html

时间: 2024-10-09 10:41:43

Codeforces 514C. Watto and Mechanism解题报告(字典树)的相关文章

codeforces 514C Watto and Mechanism (分段暴力)

codeforces 514C Watto and Mechanism (分段暴力) 题意: 给出一个包含n个单词的字典,给出m个待查询单词,如果单词在有且仅有一个字符不相同的情况下可以在字典里找到,则输出YES,否则输出NO 限制: 0 <= n,m <= 3*10^5; 总字符长度不大于6*10^5 思路: 分段暴力. 以查询单词长度为500分段: 查询单词长度<500则:采用set查询,复杂度为600*500*500=1.5*10^8 查询单词长度>500则:暴力查询,复杂度

Codeforces 514C Watto and Mechanism(字典树)

题目链接  Watto and Mechanism 题意  给出n个串(相当于字典),然后给出m个询问. 每个询问以字符串的形式给出,你需要改变这个字符串中的任意一个字符 (必须改变且只能改变一个) 如果改变之后可以成为n个串中的一个字符串,则输出YES, 否则输出NO. 字母集合为{a, b, c} 考虑字典树. 首先把n个单词插入字典树中. 询问的时候用dfs,flag表示搜索到当前是否已经改变过一个字符. 如果已经改变过那只能按照当前剩下的字符串一条路查询下去. 否则可以按老字符或新字符进

ACM:统计难题 解题报告-字典树(Trie树)

统计难题 Time Limit:2000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u Submit Status Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input 输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignati

ACM: Find MaxXorSum 解题报告-字典树

Find MaxXorSum Time Limit:2000MS Memory Limit:65535KB 64bit IO Format: Description Given n non-negative integers, you need to find two integers a and b that a xor b is maximum. xor is exclusive-or. Input Input starts with an integer T(T <= 10) denoti

tries树第一题 codeforces 514C - Watto and Mechanism

题目链接 题意: 输入a个已知字符串和b个待检测字符串.问待检测字符串是否可以由某个已知字符串改变且只改变一个字母得到.可以输出YES,否则NO. 思路: 用trie树储存已知字符串.dfs改变一个字母看能否匹配. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> using namespace std;

Codeforces Round #259 (Div. 2) 解题报告

终于重上DIV1了.... A:在正方形中输出一个菱形 解题代码: 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2014年08月01日 星期五 23时27分55秒 4 5 #include<vector> 6 #include<set> 7 #include<deque> 8 #include<stack> 9 #include<bitset> 10 #inclu

Codeforces 459(#261 (Div. 2) ) 解题报告

A:给你一个正方形的两点,让你求其余亮点 解法:乱搞 解题代码: 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2014年08月15日 星期五 23时24分04秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<

Codeforces 450(#257 (Div. 2) ) 解题报告

A: 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月19日 星期六 21时01分28秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bits

Codeforces Round #262 (Div. 2)解题报告

详见:http://robotcator.logdown.com/posts/221514-codeforces-round-262-div-2 1:A. Vasya and Socks   http://codeforces.com/contest/460/problem/A 有n双袜子,每天穿一双然后扔掉,每隔m天买一双新袜子,问最多少天后没有袜子穿.. 简单思维题:以前不注重这方面的训练,结果做了比较久,这种题自己边模拟边想.不过要多考虑trick ```c++ int main(){ i