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

codevs3013单词背诵

时间:2016-05-08 18:16:48      阅读:253      评论:0      收藏:0      [点我收藏+]

标签:

/*
手打的哈希+线性的维护
第一问:hash一下 并且用个h记录某个单词要背的
第二问:线性的跑一边 
开始队列里装下前一些单词使这一坨符合要求 并且记录出现次数num 
然后开始从前面删
删除的条件:要么是非法的单词(h值为0)
            要么num值大于1
如果删不了就在进来一个 更新num
直到跑完  这过程中每次更新l 
注意这样有极端数据 如果第一问答案为 0 需要特判一下 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#define maxm 100100
#define maxn 100010
#define mod 100007
#define p 17
using namespace std;
char s[maxn][12],ss[maxn][12];
int n,m,f[maxn],a[maxm],ans,l=maxn;
int h[maxn],num[maxn],vis[maxn],head,tail;
int get_hash(char *str)
{
    int len=strlen(str),hash=0;
    for(int i=0;i<=len-1;i++)
      hash=(hash*p+str[i]-a)%mod;
    return hash;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
      scanf("%s",s[i]);
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
      {
          scanf("%s",ss[i]);
        f[get_hash(ss[i])]=1;
      }
    for(int i=1;i<=n;i++)
      {
          int tmp=get_hash(s[i]);
          if(f[tmp]==1)
          {
            ans++;
            h[tmp]=1;
          }
      }
    int si=0;
    head++;
    while(tail<=m)
      {
          int tmp=get_hash(ss[++tail]);
          if(h[tmp])
          {
              if(vis[tmp]==0)
              si++;
              num[tmp]++;
              vis[tmp]=1;
          }
          if(si==ans&&si!=0)
            {
                int x=get_hash(ss[head]);
                while(head<tail&&(h[x]==0||num[x]>1))
                  {
                      if(h[x])
                  num[x]--;
                x=get_hash(ss[++head]);
              }
            l=min(l,tail-head+1);
          }
      }
    if(ans)printf("%d\n%d\n",ans,l);
    else printf("0\n0");
}

 

codevs3013单词背诵

标签:

原文地址:http://www.cnblogs.com/yanlifneg/p/5471038.html

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