map集合应用——单词背诵

单词背诵

题目描述

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

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

输入格式

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

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

输出格式

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

样例 #1

样例输入 #1

3
hot
dog
milk
5
hot
dog
dog
milk
hot

样例输出 #1

3
3

提示

数据规模与约定

  • 对于 30 % 30\% 30% 的数据, n ≤ 50 n \le 50 n50 m ≤ 500 m \le 500 m500
  • 对于 60 % 60\% 60% 的数据, n ≤ 300 n \le 300 n300 m ≤ 5000 m \le 5000 m5000
  • 对于 100 % 100\% 100% 的数据, n ≤ 1000 n \le 1000 n1000 m ≤ 1 0 5 m \le 10^5 m105

思路

第一问很简单,我们可以直接用map集合来存储单词,但单词的出现的个数为1,就让答案++。

第二问:要求文章中包含最多要背单词的最短的连续段的长度,这句话的意思就是说寻找某长度的段落包含之前背过的单词数量,那么我们可以用 l l l来表示连续长度的上端点。

我们什么时候 l l l要++呢?

  • 情况1:当同一个单词出现了两次,那么l++,并将此时的单词数–。
  • 情况2:当不存在此单词,l++。

总结:对于连续性的题目,我们均采取类似双指针的写法(也就是对一连续区间进行分析)

代码

//直接用map映射

#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>

using namespace std;

const int N = 1e5+10;

map<string,int>s,f;
int n,m;
string a[N];

int main(){
    cin>>n;
    
    int minv=2e9;
    for(int i=1;i<=n;i++){
        string b;
        cin>>b;
        // s[a]++;
        f[b]++;
    }
    
    cin>>m;
    
    int ans1=0,ans2=0;
    int cnt=0;
    int l=1;
    for(int i=1;i<=m;i++){
        cin>>a[i];
        if(f[a[i]])s[a[i]]++;
        if(s[a[i]]==1)ans1++,ans2=i-l+1;
        while(l<=i){
            if(!f[a[l]]){
                l++;
                continue;
            }
            if(s[a[l]]>=2){
                s[a[l]]--;
                l++;
                continue;
            }
            break;
        }
        ans2=min(ans2,i-l+1);
    }
    
    
    cout<<ans1<<endl<<ans2;
    
    return 0;
}
  • 16
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

green qwq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值