zoukankan      html  css  js  c++  java
  • 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 certain way. Initially the memory of the mechanism is filled with n strings. Then the mechanism should be able to process queries of the following type: "Given string s, determine if the memory of the mechanism contains string t that consists of the same number of characters as s and differs from s in exactly one position".

    Watto has already compiled the mechanism, all that's left is to write a program for it and check it on the data consisting of n initial lines and m queries. He decided to entrust this job to you.

    Input

    The first line contains two non-negative numbers n and m (0 ≤ n ≤ 3·105, 0 ≤ m ≤ 3·105) — the number of the initial strings and the number of queries, respectively.

    Next follow n non-empty strings that are uploaded to the memory of the mechanism.

    Next follow m non-empty strings that are the queries to the mechanism.

    The total length of lines in the input doesn't exceed 6·105. Each line consists only of letters 'a', 'b', 'c'.

    Output

    For each query print on a single line "YES" (without the quotes), if the memory of the mechanism contains the required string, otherwise print "NO" (without the quotes).

    Sample test(s)
    Input
    2 3
    aaaaa
    acacaca
    aabaa
    ccacacc
    caaac
    Output
    YES
    NO
    NO

    题意:输入n+m串字符串,判断m中的每个字符串是否在前n个字符串中有满足条件(1.长度相同;2.最多只有一个字符不一样)的对应字符串;
    分析:字典树+dfs 据说暴力也能过;

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 
     5 using namespace std;
     6 
     7 const int MAXN=1000010; //其实300000以上就够 习惯开大些
     8 int dic[MAXN][5],val[MAXN],cnt,flag,ok;
     9 
    10 void inst(char *s)  //插入Trie树 数组为链
    11 {
    12     int u=0,v,len;
    13     len=strlen(s);
    14     for(int i=0;i<len;i++)
    15     {
    16         v=s[i]-'a'+1;   //分别标记 a b c 为 1 2 3  其实0 1 2 也可以 不过为了与初始化的值区分开 便于查错 就这样做了
    17         if(!dic[u][v])   //如果此节点未被编码过  
    18         {
    19             dic[u][v]=++cnt;  //编码此数组 其实就是形成链表的过程
    20             memset(dic[cnt],0,sizeof(dic[cnt]));  //初始化该节点下所属的字母
    21         }
    22         u=dic[u][v];   //取出该节点编码 作用:1、便于对该节点赋值操作 2、生成链表或继续访问链表
    23         if(i==len-1) val[u]=1;  //如果此时该字符串已结束 标记结束时的编码值
    24     }
    25 }
    26 
    27 bool dfs(char  *s,int r,int u,int num) //括号里面的内容分别为  字符串s 字符下标r 字符的节点u 不同字母个数num
    28 {
    29     if(s[r]) //如果该字符串没有结束
    30     {
    31         int v=s[r]-'a'+1;  // a b c 转换为 1 2 3 与插入时保持一致 
    32         if(dic[u][v])   //如果该字母与树上的字母有匹配的连接方式
    33         {
    34             if(dfs(s,r+1,dic[u][v],num)) {return true;}  //继续深搜 一直到底 如果中途不满足条件就会跳出
    35         }
    36         if(!num)   //num最多有1个 只有为0的时候才可替换此处字母继续访问链标 
    37         {
    38             for(int i=1;i<=3;i++)
    39             {
    40                 if(i!=v&&dic[u][i])   //与原来字母不相同 并且树上存在匹配方式
    41                     if(dfs(s,r+1,dic[u][i],num+1))   //相当与把当前字母替换为其他字母 然后继续访问
    42                     return true;
    43             }
    44         }
    45     }
    46     else if(num&&val[u]) return true;  //字符串已结束 判断是否有同样长度的字符串
    47     return false;
    48 }
    49 
    50 int main()
    51 {
    52     int n,m;
    53     char s[MAXN];   //这里如果用string会暴MEMORY  这里不大明白为什么 谅
    54 
    55     memset(dic[0],0,sizeof(dic[0]));  //一次性全部初始化也可
    56     memset(val,0,sizeof(val));    //初始化所有编码值
    57     cnt=0;    //初始化编码号
    58 
    59     scanf("%d%d",&n,&m);
    60     getchar();
    61     for(int i=0;i<n;i++)  //插入字符操作 一开始考虑用set去存字符串 结果查看测试数据时发现其实没必要
    62     {
    63         scanf("%s",s);
    64         inst(s);
    65     }
    66 
    67     for(int i=0;i<m;i++) 
    68     {
    69         scanf("%s",&s);
    70         flag=dfs(s,0,0,0);   //flag标记该串是否满足条件
    71         if(flag) printf("YES
    ");
    72         else printf("NO
    ");
    73     }
    74 }


  • 相关阅读:
    2012 人民搜索 实习生招聘 笔试题(转)
    招行两地一卡——PayPal美元兑换人民币的最佳解决方案
    PHP上传图片类
    PHP获取随机数
    Linux下解压RAR软件下载和解压.zip和.rar文件
    Zend Framework学习(1)简介
    编程指导
    Zend Framework数据库操作总结
    Zend Framework学习(4)之前端控制器
    参数是否为FALSE的区别
  • 原文地址:https://www.cnblogs.com/wsaaaaa/p/4294405.html
Copyright © 2011-2022 走看看