码迷,mamicode.com
首页 > 其他好文 > 详细

单词背诵

时间:2019-03-26 01:07:12      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:个数   name   for   amp   pen   har   stdout   输入格式   get   

/*问题描述

灵梦有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<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
using namespace std;
const int maxn=1e3+5;
const int maxm=1e5+5;
const int maxlen=20;
const int N=1000007;
int n,m,pre[maxm],first[N+5],next[maxn],ans=0,cnt[maxn];//cnt[i]琛ㄧず鍗曡瘝i鑳屼簡澶氬皯娆?
bool visit[maxn];
char a[maxn][maxlen],b[maxm][maxlen];
inline int hash(char *ch){
    int ans=0;
    int len=strlen(ch);
    for(int i=0;i<len;++i){
        ans=(ans*31+ch[i]-‘a‘)%N;
    }
    return ans%N;
}
inline bool same(char *a,char *b){
    int la=strlen(a);
    int lb=strlen(b);
    if(la!=lb)return 0;
    for(register int i=0;i<la;++i){
        if(a[i]!=b[i])return 0;
        }    
    return 1;
}
inline void add(char *ch,int pos){
    int key=hash(ch);
    for(int i=first[key];i;i=next[i]){
    if( same( ch , a[i]) )return;
    }
    next[pos]=first[key];
     first[key]=pos;
}
inline void find(char *ch,int pos){
    int key=hash(ch);
    for(register int i=first[key];i;i=next[i]){
        if( same( ch , a[i] ) ){
            pre[pos]=i;
            if(!visit[i])ans++;
            visit[i]=1;
            }
    }
}
int main()
{
    /*freopen("p386p.in","r",stdin);
    freopen("p386p.out","w",stdout);*/
    scanf("%d",&n);
    gets(a[0]);
    for(register int i=1;i<=n;i++){
    gets(a[i]);
    add(a[i],i);
    }
    scanf("%d",&m);
    gets(b[0]);
    for(register int i=1;i<=m;i++)
    {
    gets(b[i]);
    find(b[i],i);
    }
    printf("%d\n",ans);
    int kk=ans;
    ans=0x7fffffff;
    int right=0,left=0,temp=0;
    while(right<=m){
        right++;
        if(!pre[right])continue;
        if(!cnt[ pre[right] ])temp++;
        cnt[ pre[right] ]++;
        while(left<=right && temp==kk){
            ans=min(ans,right-left+1);
            if(cnt[ pre[left] ]==1)temp--;
            cnt[  pre[left] ]--;
            left++;
        }
        
    }
    printf("%d",ans);
    return 0;
}

单词背诵

标签:个数   name   for   amp   pen   har   stdout   输入格式   get   

原文地址:https://www.cnblogs.com/a-blog-of-taojiayi-2003/p/10597748.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!