1. 程式人生 > >CODEVS——T 3013 單詞背誦

CODEVS——T 3013 單詞背誦

animate spa main define esc slide pad 題目 output

http://codevs.cn/problem/3013/

時間限制: 1 s 空間限制: 128000 KB 題目等級 : 鉆石 Diamond 題目描述 Description

靈夢有n個單詞想要背,但她想通過一篇文章中的一段來記住這些單詞。

文章由m個單詞構成,她想在文章中找出連續的一段,其中包含最多的她想要背的單詞(重復的只算一個)。並且在背誦的單詞量盡量多的情況下,還要使選出的文章段落盡量短,這樣她就可以用盡量短的時間學習盡可能多的單詞了。

輸入描述 Input Description

第1行一個數n,

接下來n行每行是一個長度不超過10的字符串,表示一個要背的單詞。

接著是一個數m,

然後是m行長度不超過10的字符串,每個表示文章中的一個單詞。

輸出描述 Output Description

輸出文件共2行。第1行為文章中最多包含的要背的單詞數,第2行表示在文章中包含最多要背單詞的最短的連續段的長度。

樣例輸入 Sample Input

3

hot

dog

milk

5

hot

dog

dog

milk

hot

樣例輸出 Sample Output

3

3

數據範圍及提示 Data Size & Hint

對於30%的數據 n<=50,m<=500;

對於60%的數據 n<=300,m<=5000;

對於100%的數據 n<=1000,m<=100000;

第一問:用Hash得到需要的單詞在文章中出現的情況

第二問:想從文章開始就將單詞入隊,保證需要背的都在隊內,然後開始縮短長度

若隊頭不是需要單詞或者在隊內的次數多余1,則將其刪除

 1 #include <algorithm>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace
std; 5 6 #define p 19 7 #define mod 100007 8 const int N(100000+10); 9 char s1[N][11],s2[N][11]; 10 int ans,n,m,num[N],need[N],vis[N],have[N]; 11 12 int Hash(char a[]) 13 { 14 int ret=0; 15 for(int i=0;i<strlen(a);i++) 16 ret=(ret*p+a[i]-a)%mod; 17 return ret; 18 } 19 20 int main() 21 { 22 scanf("%d",&n); 23 for(int i=1;i<=n;i++) scanf("%s",s1[i]); 24 scanf("%d",&m); int len=m; 25 for(int i=1;i<=m;i++) 26 scanf("%s",s2[i]),have[Hash(s2[i])]=1; 27 for(int i=1;i<=n;i++) 28 { 29 int ha=Hash(s1[i]); 30 if(have[ha]) ans++,need[ha]=1; 31 } 32 for(int cnt=0,head=1,tail=0;tail<=m;) 33 { 34 int ha=Hash(s2[++tail]); 35 if(need[ha]) 36 { 37 if(!vis[ha]) cnt++; 38 num[ha]++; vis[ha]=1; 39 } 40 if(cnt==ans&&ans) 41 { 42 int x=Hash(s2[head]); 43 for(;head<tail&&(num[x]>1||!need[x]);) 44 { 45 if(need[x]) num[x]--; 46 x=Hash(s2[++head]); 47 } 48 len=min(len,tail-head+1); 49 } 50 } 51 if(!ans) printf("0\n0"); 52 else printf("%d\n%d",ans,len); 53 return 0; 54 }

CODEVS——T 3013 單詞背誦