Problem-solving ideas
Consider passing both the words to be memorized and the words in the article through H ash HashH a s h is transformed into ahash hashh a s h value, and then you can directly find the maximum number of words to be memorizedmaxn maxnm a x n .
For the second question, consider the ruler method:
- Initialize l = r = ml=r=ml=r=m ; (It’s okay to start from 0)
- Every time lll Move to the left, if it is a word to recite, thennum + + num++n u m++
- If num == maxn num==maxnn u m==m a x n , consider whether r can be moved to the left (not the words to be memorized can be moved), and then update the answerans = min (ans, r − l) ans=min (ans, rl)a n s=m i n (a n s ,r−l ) Finally cancelrrThe word at position r , see the code for details. .
Code
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int p=131,mod=1000007;
int n,m,a[1010],b[100010],v[2000000],use[2000000],vv[2000000],maxn,num,ans=2147483600,r;
string x;
int hash(string s)
{
int cnt=0;
for(int i=0;i<s.size();i++)
{
cnt=(cnt*p+s[i])%mod;
}
return cnt;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>x;
a[i]=hash(x);
v[a[i]]=1;
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
cin>>x;
b[i]=hash(x);
if(v[b[i]]&&!use[b[i]])
{
maxn++;
use[b[i]]=1;
}
}
if(maxn==0){
printf("0\n0");
return 0;
}
else printf("%d\n",maxn);
r=0;
for(int l=1;l<=m;l++)
{
while(num<maxn&&r<m)
{
r++;
if(v[b[r]])
{
if(vv[b[r]]==0)
num++;
vv[b[r]]++;
}
}
if(num==maxn)
{
while(!v[b[l]])
l++;
ans=min(ans,r-l+1);
if(vv[b[l]]>=1)
{
if(vv[b[l]]==1)
num--;
vv[b[l]]--;
}
}
}
printf("%d",ans);
}