题意,一本书有n页,每一页有一个知识点,问最少需要连续阅读多少页,能读完所有的知识点
分析,假设从l开始读,那么需要找到他的结束位置r,如果从l+1开始,那么如果l的知识点在[l,r]出现一次,那么右边界需要读取到l的知识点再次出现的位置,否则,不变,左右边界慢慢向右蠕动
尺取法
#include<iostream> #include<algorithm> #include<map> #include<cstring> #include<cstdio> using namespace std; const int maxn=100000+5; int p[maxn]; int n; int main(){ while(~scanf("%d",&n)){ int tmp=0; map<int ,int>v; for(int i=1;i<=n;i++){ scanf("%d",p+i); v[p[i]]++; } tmp=v.size(); v.clear(); int ans=n+1,r=1,res=0; for(int i=1;i<=n;i++){ while(res<tmp&&r<=n){ v[p[r]]++; if(v[p[r]]==1) res++; r++; } if(res==tmp) ans=min(ans,r-i); else break; if((--v[p[i]])==0) res--; } cout<<ans<<endl; } return 0; }