Word recitation [CodeVS3013] hash

Keywords: PHP

Problem description

Reimu has n words she wants to memorize, but she wants to remember them through a passage in an article.

The article is composed of m words. She wants to find a continuous paragraph in the article, which contains the most words she wants to memorize (only one repeated one). And in the case of reciting as many words as possible, also make the selected paragraphs as short as possible, so that she can learn as many words as possible in the shortest time.

Input format

The first line has a number of n, and the next n lines each contain a string no longer than 10, representing a word to memorize.

Then there is a number m, followed by a string of M lines no longer than 10, each representing a word in the article.

Output format

The output file has 2 lines in total. The first line is the maximum number of words to memorize in the article, and the second line is the length of the shortest continuous section containing the most words to memorize in the article.

sample input

3
hot
dog
milk
5
hot
dog
dog
milk
hot

sample output

3
3

HINT

For 30% of data, n < = 50, m < = 500;

For 60% of the data, n < = 300, m < = 5000;

For 100% data, n < = 1000, m < = 100000;

Time limit: 1s

Space limit: 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;
}

 

Posted by lunarul on Wed, 16 Oct 2019 14:39:06 -0700