这道题,其实就是搜索,但是有技巧,找到从第一个元素(记为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; }