• CODEVS——T 3013 单词背诵


     http://codevs.cn/problem/3013/

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 钻石 Diamond
     
     
    题目描述 Description

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

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

    输入描述 Input Description

    第1行一个数n,

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

    接着是一个数m,

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

    输出描述 Output Description

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

    样例输入 Sample Input

    3

    hot

    dog

    milk

    5

    hot

    dog

    dog

    milk

    hot

    样例输出 Sample Output

    3

    3

    数据范围及提示 Data Size & Hint

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

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

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

    第一问:用Hash得到需要的单词在文章中出现的情况

    第二问:想从文章开始就将单词入队,保证需要背的都在队内,然后开始缩短长度

                  若队头不是需要单词或者在队内的次数多余1,则将其删除

     1 #include <algorithm>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 
     6 #define p 19
     7 #define mod 100007
     8 const int N(100000+10);
     9 char s1[N][11],s2[N][11];
    10 int ans,n,m,num[N],need[N],vis[N],have[N];
    11 
    12 int Hash(char a[])
    13 {
    14     int ret=0;
    15     for(int i=0;i<strlen(a);i++)
    16         ret=(ret*p+a[i]-'a')%mod;
    17     return ret;
    18 }
    19 
    20 int main()
    21 {
    22     scanf("%d",&n);
    23     for(int i=1;i<=n;i++) scanf("%s",s1[i]);
    24     scanf("%d",&m); int len=m;
    25     for(int i=1;i<=m;i++)
    26         scanf("%s",s2[i]),have[Hash(s2[i])]=1;
    27     for(int i=1;i<=n;i++)
    28     {
    29         int ha=Hash(s1[i]);
    30         if(have[ha]) ans++,need[ha]=1;
    31     }
    32     for(int cnt=0,head=1,tail=0;tail<=m;)
    33     {
    34         int ha=Hash(s2[++tail]);
    35         if(need[ha])
    36         {
    37             if(!vis[ha]) cnt++;
    38             num[ha]++; vis[ha]=1;
    39         }
    40         if(cnt==ans&&ans)
    41         {
    42             int x=Hash(s2[head]);
    43             for(;head<tail&&(num[x]>1||!need[x]);)
    44             {
    45                 if(need[x]) num[x]--;
    46                 x=Hash(s2[++head]);
    47             }
    48             len=min(len,tail-head+1);
    49         }
    50     }
    51     if(!ans) printf("0
    0");
    52     else printf("%d
    %d",ans,len);
    53     return 0;
    54 }
    ——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
  • 相关阅读:
    Webpack的学习总结(1)
    mybatis-plus逻辑删除
    vscode编译调试C/C++多文件——linux(makefile)
    vscode配置调试C/C++程序——linux环境(命令行编译)
    shell编程题(二十二)
    shell编程题(二十三)
    shell编程题(二十一)
    shell编程题(二十)
    GTK开发视频播放器
    C语言实现LRU缓存(二)
  • 原文地址:https://www.cnblogs.com/Shy-key/p/7352501.html
Copyright © 2020-2023  润新知