[Hash] recite word CodeVS3013

Problem Description

Reimu n words you want to have back, but she wants to remember these words by a period of one article.

Article consists of m words, she wanted to find a continuous period in the article, most of which contain the word she wanted back (repeating only count as one). And in as much quantity word recitation of the situation, but also to make the article a paragraph elected as short as possible, so she could use the shortest possible time to learn as much as possible the word.

Input Format

A first row number n, the next n lines each string is no longer than 10, to represent a word back.

Followed by a number m, and 10 m lines string length does not exceed, each representing a word in the article.

Output Format

Total output file 2 line. The number of words you want to back up to the first acts of the article contained in the second row contains the length of up to represent the word back to the continuous segment of the shortest in the article.

SAMPLE INPUT

3
hot
dog
milk
5
hot
dog
dog
milk
hot

Sample Output

3
3

HINT

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

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

To 100% of the data n <= 1000, m <= 100000;

Time limit: 1s

Space limitations: 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++;
        }
        years = min (years r- l); 
    } 
    Printf ( " % d " , year);
    return  0 ; 
}

 

Guess you like

Origin www.cnblogs.com/hfang/p/11240072.html