http://poj.org/problem?id=3320
题目大意:
某人读一本书,要看完所有的知识点,这本书共有P页,第i页恰好有一个知识点ai,(每一个知识点都有一个整数编号)。全书同一个知识点可能会被提到多次,他希望阅读其中一些连续的页把所有知识点都读到,给定每页所读到的知识点,求最少的阅读页数。
思路:
和上一题一样,也是尺取法的应用。
假设从某一页s开始阅读,为了覆盖所有的知识点读到t页,这样的话如果从s+1开始阅读,那么必须读到t'>=t位置,故可以用尺取法。
用上Map来统计次数,取出前一项要把对应的知识点的编号次数-1.详见代码。
#include<cstdio>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int MAXN=1000000+10;
const int INF=0x3fffffff;
int a[MAXN];
set<int> s;
map<int,int> x;
int main()
{
int p;
while(~scanf("%d",&p))
{
for(int i=0;i<p;i++)
scanf("%d",&a[i]);
s.clear();
for(int i=0;i<p;i++)
s.insert(a[i]);
int n=s.size();
int s=0,t=0,ans=INF,cnt=0;
while(true)
{
while(cnt<n && t<p)
{
if(x[ a[t++] ]++==0)
cnt++;
}
if(cnt<n) break;
ans=min(ans,t-s);
if(--x[a[s++]]==0)
cnt--;
}
printf("%d\n",ans);
}
return 0;
}