POJ 3320 Jessica's Reading Problem(尺取法)


1.首先我们需要记录知识点总数;
2.其次定义map<int,int>来存储我们目前每个知识点出现的次数;
3.对于每个s指向开头,我们定义t指向末尾然后逐个遍历,直到所有的知识点都被覆盖,此时如果s指向的知识点出现的次数不为1(肯定大于0,因为都覆盖了),说明后面有同样的知识点,我们往后移s直到s指向的知识点出现的次数为1,此时t-s就是覆盖的页数;
4.然后依照同样规律继续往后移t,全覆盖了再移s

代码:

#include<iostream>
#include<set>
#include<map>
using namespace std;
template <class T> inline void read(T &res){
	char c;do{c=getchar();}while(c<'0'||c>'9');
	res=c-'0';while(c=getchar(),c>='0'&&c<='9') res=res*10+(c-'0');
}
const int MAX_N=1e6+99;
int n,P,p[MAX_N];
void solve(){
	int s=0,t=0,ans=0,res=P;
	map<int,int> cnt;
	while(t<P){
		if(cnt[p[t]]==0) ans++;
		cnt[p[t++]]++;
		if(ans==n){
			while(cnt[p[s]]!=1) cnt[p[s++]]--;
			res=min(res,t-s);
			cnt[p[s++]]=0; ans--;
		}
	}
	cout<<res;
}
int main(){
	read(P);
	set<int> st;
	for(int i=0;i<P;i++){
		read(p[i]);
		st.insert(p[i]);
	}
	n=st.size();
	solve();
	return 0;
}