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
",ans);
39         }
40     }
41     return 0;
42 }
View Code
原文地址:https://www.cnblogs.com/bin-gege/p/6417387.html