对数组保存一组下标(起点,终点),然后根据实际情况交替推进两个端点直到得出答案。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> using namespace std; int N,S,K; int a[100005]; int main() { cin>>K; while(K--) { cin>>N>>S; for(int i=0;i<N;i++) { cin>>a[i]; } int res=N+1; //尺取法 int s=0,t=0,sum=0; for(;;) { while(t<N&&sum<S) sum+=a[t++]; if(sum<S) break; res=min(res,t-s); sum-=a[s++]; } if(res>N) cout<<0<<endl; else cout<<res<<endl; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<stdio.h> #include<set> #include<map> using namespace std; int P; int a[1000005]; int main() { scanf("%d",&P); //所有知识点 set<int> se; //知识点->出现次数 映射 map<int,int> m; for(int i=0;i<P;i++) { scanf("%d",&a[i]); se.insert(a[i]); } //知识点个数 int n=se.size(); //尺取法 int s=0,t=0,num=0,ans=P; while(true) { while(t<P&&num<n) { if(m[a[t++]]++==0) num++; } if(num<n) break; ans=min(ans,t-s); if(--m[a[s++]]==0) num--; } printf("%d",ans); }