单词背诵CodeVS3013 哈希

Posted hfang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单词背诵CodeVS3013 哈希相关的知识,希望对你有一定的参考价值。

问题描述

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

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

输入格式

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

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

输出格式

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

输入样例

3
hot
dog
milk
5
hot
dog
dog
milk
hot

输出样例

3
3

HINT

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

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

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

时间限制:1s

空间限制:128MB

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
using namespace std;
typedef unsigned long long uLL;
map<uLL,int>vis,Map;
map<int,uLL>b;
char a[12];
int gethash(string s)

    int len=s.length();
    uLL sum(0);
    for(int i=0;i<len;i++)
        sum=sum*131+s[i]-a;
    return sum;

int main()

//    freopen("p386.in","r",stdin);
//    freopen("p386.out","w",stdout);
    int n,m,sum=0;
    cin>>n;
    for(int i=1;i<=n;i++)
    
        scanf("%s",a);
        Map[gethash(a)]=1;
    
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    
        scanf("%s",a);
        b[i]=gethash(a);
        if(  Map[b[i]] && !vis[b[i]] )
        
            sum++;
            vis[b[i]]=1;
        
    
    printf("%d\n",sum);
    vis.clear();
    int l=0,r=1,ans(1<<30),sumx=0;
    while(r<=m)
    
        while(r<=m)
        
            if(!vis[b[r]] && Map[b[r]] ) sumx++;
            vis[b[r]]++;
            r++;
            if(sumx==sum) break;
        
        while(l<r && ( !Map[b[l]] || vis[b[l]]>1 ))
        
            vis[  b[l] ]--;
            l++;
        
        ans = min(ans,r-l);
    
    printf("%d",ans);
    return 0;

 

以上是关于单词背诵CodeVS3013 哈希的主要内容,如果未能解决你的问题,请参考以下文章

CODEVS——T 3013 单词背诵

[CODEVS3031] 单词背诵 - 字符串hash

题解 P1381 单词背诵(哈希,队列)

[codeVS1204] 单词背诵

[Codevs 1230]元素查找(手写哈希表)

codevs1004四子连棋[BFS 哈希]