【尺取】POJ 3320

POJ 3320 Jessica’s Reading Problem

题意:一本书P页,第i页有ai知识点,问你至少从某一处开始连续要翻多少页才能复习完所有的知识点,不能跨页翻。

思路:《挑战程序设计》上的尺取法的经典例题,set用来求出所有不重复知识点的个数,map用来计算是否有新出现的的知识点。
1.左端点s,右端点t,目前复习的知识点num初始化为0;
2.只要有t < P,num < n,且出现新的知识点counts[a[t++]]++==0,num++;
3.如果num < n,则无法解决该题。否则更新答案,min(res,t-s);
4.从s开始缩小范围,若某一知识点的次数为零,则num–;回归2.

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <iostream>
using namespace std;
const int maxn = 1000000+10;
int P;
int a[maxn];
int main()
{
    while(~scanf("%d",&P)){
        set<int> all;
        for(int i=0;i<P;i++){
            scanf("%d",&a[i]);
            all.insert(a[i]);
            //去重,升序排序,支持集合的交(set_intersection),差(set_difference) 并(set_union),对称差(set_symmetric_difference)
        }
        int n = all.size();
        int s = 0,t = 0,num = 0;
        map<int ,int > counts;
        int res = P;
        for(;;){
            while(t<P && num<n){
                if(counts[a[t++]]++ == 0){
                    num++;
                }
            }
            if(num<n) break;
            res = min(res,t-s);
            if(--counts[a[s++]] == 0){
                num--;
            }
        }
        printf("%d\n",res);
    }
    return 0;
}
posted @ 2016-04-21 18:53  霜降sma  阅读(113)  评论(0编辑  收藏  举报