这道题,其实就是搜索,但是有技巧,找到从第一个元素(记为ptr1)开始的包含Q个整数的最短区间长ptr2,然后在对ptr2和ptr1进行搜索,具体的请看代码。
#include<iostream>
using namespace std;
#define L 100010
int a[L]={0},b[L]={0};
bool f[L]={false},g[L]={false};
int main()
{
int N,M;
while(cin>>N>>M)
{
int i,k=0,x,s=0,sum=0,ptr1=1,ptr2=1,ans=1<<25;
if((N+M)==0) break;
memset(f,false,sizeof(f));
memset(g,false,sizeof(g));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(i=1;i<=N;i++) cin>>a[i];
while(M--)
{
cin>>k;
sum=0;ans=1<<25;
memset(f,false,sizeof(f));
memset(g,false,sizeof(g));
memset(b,0,sizeof(b));
for(i=0;i<k;i++)
{
cin>>x;
if(!f[x]) sum++;
f[x]=g[x]=true;
}
s=0;ptr1=ptr2=1;
for(;s<sum;ptr2++)
{
if(g[a[ptr2]])
{
s++;g[a[ptr2]]=false;
}
b[a[ptr2]]++;
}
ptr2--;
if(ans>(ptr2-ptr1+1)) ans=ptr2-ptr1+1;
while(ptr1<=ptr2)
{
b[a[ptr1]]--;
if(b[a[ptr1]]==0 && f[a[ptr1]])
{
while(ptr2<=N && (a[ptr1]!=a[ptr2]))
{
ptr2++;b[a[ptr2]]++;
}
if(ptr2>N) break;
}
ptr1++;
if(ans>(ptr2-ptr1+1)) ans=ptr2-ptr1+1;
}
if(k==1) ans=1;
cout<<ans<<endl;
}
}
return 1;
}
浙公网安备 33010602011771号