【CodeVS3013】单词背诵

Description

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

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

Input

第1行一个数n,

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

接着是一个数m,

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

Output

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

Sample Input

3

hot

dog

milk

5

hot

dog

dog

milk

hot

Sample Output

3

3

HINT

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

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

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

题解

map

第二问维护一个队列一样的东西,先一直读,直到队列中有ans1个元素,然后一个一个读,在保证队列中元素个数不变的情况下删除队头元素。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
typedef unsigned long long ull;
map<ull,int> vis,Map;
map<int,ull> b;
ull hash(char *s)
{
    int len = strlen(s);
    ull sum = 0;
    for (int i=0;i<len;i++)
        sum = sum*131+s[i] - 'a';
    return sum;
}
int main()
{
    int n,m,sum = 0;
    char a[12];
    scanf("%d",&n);
    for (int i=0;i<n;i++)
    {
        scanf("%s",a);
        Map[hash(a)] = 1;
    }
    scanf("%d",&m);
    for (int i=1;i<=m;i++)
    {
        scanf("%s",a);
        b[i] = hash(a);
        if (Map[b[i]] && !vis[b[i]])
        {
            sum++;
            vis[b[i]] = 1;
        }
    }
    printf("%d\n",sum);
    vis.clear();
    int h=0,t=1,sumx=0,minx=0x7ffffff;
    while (t<=m)
    {
        while (t<=m)
        {
            if (!vis[b[t]] && Map[b[t]]) sumx++;
            vis[b[t]] ++;
            t++;
            if (sumx == sum) break;
        }
        while (h<t && (vis[b[h]]>1 || !Map[b[h]]))
        {
            vis[b[h]] --;
            h++;
        }
        minx = min(minx,t-h);
    }
    printf("%d",minx);
}

 手打哈希(快)

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 1010
#define M 100010
#define mod 100007
#define p 17
using namespace std;
int hash[mod],b[mod],vis[mod];
int get_hash(char *s)
{
    int len = strlen(s),sum = 0;
    for (int i=0;i<len;i++)
        sum = (sum*p+s[i] - 'a')%mod;
    return sum;
}
int main()
{
    int n,m,sum = 0;
    char a[12];
    scanf("%d",&n);
    for (int i=0;i<n;i++)
    {
        scanf("%s",a);
        hash[get_hash(a)] = 1;
    }
    scanf("%d",&m);
    for (int i=1;i<=m;i++)
    {
        scanf("%s",a);
        b[i] = get_hash(a);
        if (hash[b[i]] && !vis[b[i]])
        {
            sum++;
            vis[b[i]] = 1;
        }
    }
    printf("%d\n",sum);
    for (int i=1;i<=mod;i++) vis[i]=0; 
    int h=0,t=1,sumx=0,minx=0x7ffffff;
    while (t<=m)
    {
        while (t<=m)
        {
            if (!vis[b[t]] && hash[b[t]]) sumx++;
            vis[b[t]] ++;
            t++;
            if (sumx == sum) break;
        }
        while (h<t && (vis[b[h]]>1 || !hash[b[h]]))
        {
            vis[b[h]] --;
            h++;
        }
        minx = min(minx,t-h);
    }
    printf("%d",minx);
}

 

posted @ 2016-05-08 16:28  mengyue  阅读(362)  评论(0编辑  收藏  举报