zoukankan      html  css  js  c++  java
  • [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 }
  • 相关阅读:
    git(重点)
    C#技巧记录——持续更新
    结点和节点的区别
    WebSocketSharp send record_stop without send record_start
    cefsharp 拦截所有请求 解决chunked导致数据接收不完整的问题
    计算mp3长度 毫秒
    pydub分割音频文件
    c# 获取文件信息
    实现一边写代码一边展示网页的效果
    c# webapi swagger Area 多级层次分组 添加header参数
  • 原文地址:https://www.cnblogs.com/J-william/p/8056093.html
Copyright © 2011-2022 走看看