zoukankan      html  css  js  c++  java
  • [HNOI2004] L语言 --trie树

    【题目描述】

    标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的。现在你要处理的就是一段没有标点的文章。

    一段文章T是由若干小写字母构成。一个单词W也是由若干小写字母构成。一个字典D是若干个单词的集合。我们称一段文章T在某个字典D下是可以被理解的,是指如果文章T可以被分成若干部分,且每一个部分都是字典D中的单词。

    例如字典D中包括单词{‘is’, ‘name’, ‘what’, ‘your’},则文章‘whatisyourname’是在字典D下可以被理解的,因为它可以分成4个单词:‘what’, ‘is’, ‘your’, ‘name’,且每个单词都属于字典D,而文章‘whatisyouname’在字典D下不能被理解,但可以在字典D’=D+{‘you’}下被理解。这段文章的一个前缀‘whatis’,也可以在字典D下被理解,而且是在字典D下能够被理解的最长的前缀。

    给定一个字典D,你的程序需要判断若干段文章在字典D下是否能够被理解。并给出其在字典D下能够被理解的最长前缀的位置。

    【输入格式】

    输入文件第一行是两个正整数n和m,表示字典D中有n个单词,且有m段文章需要被处理。之后的n行每行描述一个单词,再之后的m行每行描述一段文章。

    其中1<=n, m<=20,每个单词长度不超过10,每段文章长度不超过1M。

    【输出格式】

    对于输入的每一段文章,你需要输出这段文章在字典D可以被理解的最长前缀的位置。

    【样例输入】

    4 3
    is
    name
    what
    your
    whatisyourname
    whatisyouname
    whaisyourname
    

    【样例输出】

    14  整段文章’whatisyourname’都能被理解

    6  前缀’whatis’能够被理解

    0  没有任何前缀能够被理解

    【提示】

    本题目一共有十个测试点,每个测试点的分数为总分数的10%。对于每个测试点来说,如果你给出的答案正确,那么你将得到该测试点全部的分数,否则得0分。

    运行时间1s内存使用640K

    【来源】

    HNOI2004

    AC自动机是啥?!

    我tire树暴力跑的飞快

     1 /*
     2     用f数组来记录在哪一个位置有一个完整的单词
     3     k数字记录 前缀长度
     4     在 j 处有一个完整的单词 一定会从 i 处转移而来
     5     仅当 j+1~i为一个单词时转移成立 
     6     每次 只从一个完整单词结束的地方开始找下一个单词
     7     找不到完整的单词就退出 找到就继续找下一个
     8     保证了长度的连续性 
     9 */
    10 #include <cstring>
    11 #include <ctype.h>
    12 #include <cstdio>
    13 
    14 const int MAXN=1000010;
    15 
    16 int n,m,tot;
    17 
    18 int k[MAXN];
    19 
    20 struct node {
    21     int next[27];
    22 };
    23 node t[MAXN];
    24 
    25 char st[21][11],pr[21][MAXN];
    26 
    27 bool f[MAXN];
    28 
    29 inline void build(int p) {
    30     int len=strlen(st[p]);
    31     int now=0;
    32     for(int i=0;i<len;++i) {
    33         int x=st[p][i]-'a'+1;
    34         if(!t[now].next[x]) t[now].next[x]=++tot;
    35         now=t[now].next[x];
    36     }
    37     f[now]=true;
    38     return;
    39 }
    40 
    41 inline void find(int p) {
    42     int len=strlen(pr[p]+1);
    43     int ans;
    44     k[0]=p;
    45     for(int i=0;i<=len;++i)    {
    46         if(k[i]!=p) continue;
    47         else ans=i;
    48         for(int now=0,j=i+1;j<=len;++j) {
    49             int x=pr[p][j]-'a'+1;
    50             now=t[now].next[x];
    51             if(!now) break;
    52             if(f[now]) k[j]=p;
    53         }
    54     }
    55     printf("%d
    ",ans);
    56 }
    57 
    58 int hh() {
    59     freopen("language3.in","r",stdin);
    60 //    freopen("language.out","w",stdout);
    61     scanf("%d%d",&n,&m);
    62     for(int i=1;i<=n;++i) 
    63       scanf("%s",st[i]),build(i);
    64     for(int i=1;i<=m;++i) 
    65       scanf("%s",pr[i]+1),find(i);
    66     return 0;
    67 }
    68 
    69 int sb=hh();
    70 int main() {;}
    题解


    作者:乌鸦坐飞机
    出处:http://www.cnblogs.com/whistle13326/
    新的风暴已经出现 怎么能够停止不前 穿越时空 竭尽全力 我会来到你身边 微笑面对危险 梦想成真不会遥远 鼓起勇气 坚定向前 奇迹一定会出现

     
  • 相关阅读:
    Linux下如何查看版本信息
    java单利模式设计
    MIT 2012 分布式课程基础源码解析-底层通讯实现
    MIT 2012分布式课程基础源码解析-事件管理封装
    MIT 2012分布式课程基础源码解析-线程池实现
    MIT 2012分布式课程基础源码解析一-源码概述
    Leetcode按Tag刷题
    网页搜集系统
    c/c++中的各种字符串转换
    gentoo装X服务器时显卡选择
  • 原文地址:https://www.cnblogs.com/whistle13326/p/7398856.html
Copyright © 2011-2022 走看看