• [codeVS1204] 单词背诵


    题目描述

    灵梦有n个单词想要背,但她想通过一篇文章中的一段来记住这些单词。

    文章由m个单词构成,她想在文章中找出连续的一段,其中包含最多的她想要背的单词(重复的只算一个)。并且在背诵的单词量尽量多的情况下,还要使选出的文章段落尽量短,这样她就可以用尽量短的时间学习尽可能多的单词了。

    输入输出格式

    输入格式:

    第1行一个数n,

    接下来n行每行是一个长度不超过10的字符串,表示一个要背的单词。

    接着是一个数m,

    然后是m行长度不超过10的字符串,每个表示文章中的一个单词。

    输出格式:

    输出文件共2行。第1行为文章中最多包含的要背的单词数,第2行表示在文章中包含最多要背单词的最短的连续段的长度。

    输入输出样例

    输入样例#1: 
    3
    hot
    dog
    milk
    5
    hot
    dog
    dog
    milk
    hot
    
    输出样例#1: 
    3
    3
    

    说明

    【数据范围】

    对于30%的数据 n<=50,m<=500;

    对于60%的数据 n<=300,m<=5000;

    对于100%的数据 n<=1000,m<=100000;

    思路

    Trie离散化一下,然后先统计一下ans1,ans2通过对离散化和的数组尺取法求出。

    代码实现

     1 #include<cstdio>
     2 #include<cstring>
     3 const int maxn=1e3+10;
     4 const int maxm=1e5+10;
     5 inline int min_(int x,int y){return x<y?x:y;}
     6 int n,m,ans,now,top,map,lng=1e9;
     7 int s[maxm],v[maxn]={1};
     8 struct tree{int tn,tp;}t[maxm][30];
     9 char ch[12];
    10 void add(int k,int i){
    11     if(ch[i]==0) return;
    12     int next=ch[i]-'a';
    13     if(!t[k][next].tn) t[k][next].tn=++top;
    14     add(t[k][next].tn,i+1);
    15 }
    16 int search(int k,int i){
    17     int next=ch[i]-'a';
    18     if(ch[i]==0){
    19         if(!t[k][0].tp) t[k][0].tp=++map;
    20         return t[k][0].tp;
    21     }
    22     if(!t[k][next].tn) return 0;
    23     return search(t[k][next].tn,i+1);
    24 }
    25 int main(){
    26     scanf("%d",&n);
    27     for(int i=1;i<=n;i++){
    28         scanf("%s",ch);
    29         add(0,0);
    30     }
    31     scanf("%d",&m);
    32     for(int i=1;i<=m;i++){
    33         scanf("%s",ch);
    34         s[i]=search(0,0);
    35         if(!v[s[i]]) v[s[i]]++,ans++;
    36     }
    37     printf("%d
    ",ans);
    38     memset(v,0,sizeof(v)),v[0]=1;
    39     for(int i=1,j=1;i<=m;i++){
    40         while(now<ans&&j<=m){
    41             if(!v[s[j]]) now++;
    42             v[s[j]]++;
    43             j++;
    44         }
    45         if(now==ans) lng=min_(lng,j-i);
    46         v[s[i]]--;
    47         if(!v[s[i]]) now--;
    48     }
    49     printf("%d
    ",lng);
    50     return 0;
    51 }
  • 相关阅读:
    Solaris+Oracle安装(详细图解)
    linux卸载和安装jdk
    UTF8, Unicode, GB2312格式串转换之C语言版
    linux安装ant
    在 Linux 平台下使用 JNI
    华为C/C++笔试题(1)
    c面试
    mongodb数据库
    YARN
    NPM(包管理器)
  • 原文地址:https://www.cnblogs.com/J-william/p/8056093.html
Copyright © 2020-2023  润新知