【CodeVS3013】单词背诵

来源:互联网 发布:java中参数是什么意思 编辑:程序博客网 时间:2024/04/29 21:16

【Description】

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


【Input】

  第1行一个数n,
  接下来n行每行是一个长度不超过10的字符串,表示一个要背的单词。
  接着是一个数m,
  然后是m行长度不超过10的字符串,每个表示文章中的一个单词。


【Output】

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


【Sample Input】

3hotdogmilk5hotdogdogmilkhot

【Sample Output】

33

【Data Size and Hint】

  对于30%的数据 n<=50,m<=500;
  对于60%的数据 n<=300,m<=5000;
  对于100%的数据 n<=1000,m<=100000;


【Solution】

  数据比较大,因此储存最优方式是哈希表。
  判断文章中单词与哈希表中相同的个数,就解决了第一问。
  第二问的方式很久没用这个思想,一时也没想出来,看了别人题解,方法就是一个l,一个r记录查找范围,范围中至少最多包含的单词每个都出现一次,根据这个思想就可以在Om的时间内解决。

const mode=100007;var n,m,ans,minl:longint;    p,num:array[0..mode] of longint;    table,used:array[0..mode] of boolean;    str:array[0..mode] of string;function hash(s:string):longint;  //哈希  var i,tmp:longint;  begin    tmp:=1; hash:=0;    for i:=1 to length(s) do begin      hash:=(hash+ord(s[i])*tmp) mod mode;      tmp:=(tmp*31) mod mode;    end;    while (table[hash]) and (str[hash]<>s) do hash:=(hash+1) mod mode;    exit(hash);  end;procedure init;  //读入要背的单词  var s:string;      i:longint;  begin    readln(n);    for i:=1 to n do begin      readln(s);      str[hash(s)]:=s;      table[hash(s)]:=true;    end;  end;procedure main;    var i,j,l,r,tot:longint;      s:string;  begin    readln(m); fillchar(used,sizeof(used),false);    for i:=1 to m do begin  //读入文章,处理最大值      readln(s);      p[i]:=hash(s);      if table[p[i]] and (not used[p[i]]) then begin        inc(ans); used[p[i]]:=true;      end;    end;    writeln(ans);    //找到最短包含最大值的长度    l:=1; r:=1; tot:=0; minl:=maxlongint;    fillchar(num,sizeof(num),0);    while (r<=m) do begin      while (r<=m) do begin        if (used[p[r]]) and (num[p[r]]=0) then inc(tot);        inc(num[p[r]]);        inc(r);        if tot=ans then break;      end;      while ((not used[p[l]]) or (num[p[l]]>1)) and (l<r) do begin        dec(num[p[l]]); inc(l);      end;      if r-l<minl then minl:=r-l;    end;    writeln(minl);   end;begin  init;  main;end.
0 0
原创粉丝点击