Codeforces Round #291 (Div. 2) C - Watto and Mechanism 字符串

【题意】给n个字符串组成的集合,然后有m个询问(0 ≤ n ≤ 3·105, 0 ≤ m ≤ 3·105) ,每个询问都给出一个字符串s,问集合中是否存在一个字符串t,使得s和t长度相同,并且仅有一个字符不同。(字符串总长度为6·105),所有字符只有a,b,c。

【题解】因为只有三种字符,用Trie最合适。先把n个字符串插入到Trie中。然后每读入一个字符串,首先枚举差异字符的位置,依次替换为另外两种字符,并检查是否合法。如果合法就直接输出YES。

显然每替换一个字符就从头检查一遍太浪费时间,所以保存字典树中差异字符位置的指针,每次从该位置开始检查即可。

我一开始是直接处理n个字符串,枚举差异字符的位置,分别替换后加入到字典树中。但是这样做会耗费相当多的空间,空间复杂度是指数级别(3^len)。MLE或者RE。但是一直返回的是WA7,QAQ找了半天错。。

#include<bits/stdc++.h>
#define eps 1e-9
#define FOR(i,j,k) for(int i=j;i<=k;i++)
#define MAXN 1000005
#define MAXM 40005
#define INF 0x3fffffff
using namespace std;
typedef long long LL;
int i,j,k,n,m,x,y,T,ans,big,cas,num,len;
bool flag;
char s[1000005];

struct Trie
{
    int ch[1000005][26];
    int val[1000005];
    int size;
    Trie()
    {
        size=1;
        memset(ch[0],0,sizeof(ch[0]));
        val[0]=0;
        val[1]=0;
    }

    int idx(char c)
    {
        return c-‘a‘;
    }

    void insert(char *s,int v)
    {
        int u=0,len=strlen(s);
        for (int i=0;i<len;i++)
        {
            int c=idx(s[i]);
            if (!ch[u][c])
            {
                memset(ch[size],0,sizeof(ch[size]));
                val[size]=0;
                ch[u][c]=size++;
            }
            u=ch[u][c];
        }
        val[u]=v;
    }

    bool exist(char *s)
    {
        int u=0,len=strlen(s);
        for (int i=0;i<len;i++)
        {
            int c=idx(s[i]);

            for (int j=0;j<3;j++)
            {
                if (c==j || ch[u][j]==0) continue;
                int u2=ch[u][j];
                flag=true;
                for (int k=i+1;k<len;k++)
                {
                    int c=idx(s[k]);
                    if (!ch[u2][c])
                    {
                        flag=false;
                        break;
                    }
                    u2=ch[u2][c];
                }
                if (flag && val[u2])
                {
                    return true;
                }
            }

            if (!ch[u][c])
            {
                return false;
            }
            u=ch[u][c];
        }
        return false;
    }
} tree;

int main()
{
    scanf("%d%d",&n,&m);
    for (i=1;i<=n;i++)
    {
        scanf("%s",s);
        tree.insert(s,1);
    }
    for (i=1;i<=m;i++)
    {
        scanf("%s",s);
        if (tree.exist(s)) puts("YES");
        else puts("NO");
    }

    return 0;
}
时间: 2024-10-05 09:52:03

Codeforces Round #291 (Div. 2) C - Watto and Mechanism 字符串的相关文章

hash+set Codeforces Round #291 (Div. 2) C. Watto and Mechanism

题目传送门 1 /* 2 hash+set:首先把各个字符串的哈希值保存在set容器里,然后对于查询的每一个字符串的每一位进行枚举 3 用set的find函数查找是否存在替换后的字符串,理解后并不难.另外,我想用64位的自然溢出wa了,不清楚 4 */ 5 /************************************************ 6 * Author :Running_Time 7 * Created Time :2015-8-5 13:05:49 8 * File N

Codeforces Round #291 (Div. 2)---C. Watto and Mechanism

Watto, the owner of a spare parts store, has recently got an order for the mechanism that can process strings in a certain way. Initially the memory of the mechanism is filled with n strings. Then the mechanism should be able to process queries of th

C. Watto and Mechanism 字典树 Codeforces Round #291 (Div. 2)

C. Watto and Mechanism time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output Watto, the owner of a spare parts store, has recently got an order for the mechanism that can process strings in a ce

Watto and Mechanism Codeforces Round #291 (Div. 2)

C. Watto and Mechanism time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output Watto, the owner of a spare parts store, has recently got an order for the mechanism that can process strings in a ce

Codeforces Round #291 (Div. 2)解题报告A.B.C.D

A - Chewbaсca and Number 大于4的倒置,小于等于4的不倒置.注意第一位如果是9则不倒置. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set>

Codeforces Round #291 (Div. 2) E - Darth Vader and Tree (DP+矩阵快速幂)

这题想了好长时间,果断没思路..于是搜了一下题解.一看题解上的"快速幂"这俩字,不对..这仨字..犹如醍醐灌顶啊...因为x的范围是10^9,所以当时想的时候果断把dp递推这一方法抛弃了.我怎么就没想到矩阵快速幂呢.......还是太弱了..sad..100*100*100*log(10^9)的复杂度刚刚好. 于是,想到了矩阵快速幂后,一切就变得简单了.就可以把距离<=x的所有距离的点数都通过DP推出来,然后一个快速幂就解决了. 首先DP递推式很容易想到.递推代码如下: for(

Codeforces Round #291 (Div. 2)

A 题意:给出变换规则,单个数字t可以变成9-t,然后给出一个数,问最小能够变成多少. 自己做的时候理解成了不能输出前导0,但是题目的本意是不能有前导0(即最高位不能是0,其余位数按照规则就好) 555555---读题仔细o(╯□╰)o 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 char

Codeforces Round #291 (Div. 2)——B&lt;set&gt;—— Han Solo and Lazer Gun

There are n Imperial stormtroopers on the field. The battle field is a plane with Cartesian coordinate system. Each stormtrooper is associated with his coordinates (x, y) on this plane. Han Solo has the newest duplex lazer gun to fight these stormtro

Codeforces Round #291 (Div. 2)(B)

水题但是WA2发了,要特别考虑斜率不存在的情况,最后的答案就是斜率不同的数目,set一下 #include<cstdio> #include<cstring> #include <iostream> #include<queue> #include <cmath> #include <set> using namespace std; const int maxn=65000+10; const int INF=1<<30