hdu 2158 最短区间版大家来找碴(双指针)
题目链接:hdu 2158 最短区间版大家来找碴
题意:
给你n个数,现在有m个询问,每个询问有q个数,让你从那n个数中选一个最小的区间,使得这个区间内包含有这q个数
题解:
双指针滚一下,具体细节看代码
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 5 const int N=1e5+7; 6 int n,m,a[N],num[N],vis[N],now,t,tmp,all; 7 8 int main(){ 9 while(scanf("%d%d",&n,&m),n+m) 10 { 11 F(i,1,n)scanf("%d",a+i); 12 while(m--) 13 { 14 scanf("%d",&t); 15 now++,all=0; 16 F(i,1,t) 17 { 18 scanf("%d",&tmp); 19 if(vis[tmp]!=now)vis[tmp]=now,all++; 20 num[tmp]=0; 21 } 22 int cnt=0,l=1,r=0,ans=INT_MAX; 23 while(r<n) 24 { 25 while(r<n&&cnt!=all) 26 { 27 r++,num[a[r]]++; 28 if(num[a[r]]==1&&vis[a[r]]==now)cnt++; 29 } 30 while(cnt==all) 31 { 32 if(num[a[l]]-1==0&&vis[a[l]]==now)break; 33 num[a[l]]--,l++; 34 } 35 if(cnt==all)ans=min(ans,r-l+1); 36 if(num[a[l]]-1==0&&vis[a[l]]==now)num[a[l]]--,cnt--,l++; 37 } 38 printf("%d\n",ans); 39 } 40 } 41 return 0; 42 }