poj 3320 Jessica's Reading Problem

来源:互联网 发布:怎样做app软件 编辑:程序博客网 时间:2024/05/28 15:08

跟poj 3061一样,都是取尺法的应用。

题目大意:

XXX要准备考试,书总共有P页,第i页恰好有一个知识点ai,书中的同一个知识点可能会被多次提到,所以他希望看其中连续的一些页的书来把所有的知识点都给看完。。

其实页数可以看作连续的序列,然后就是要求出一个子序列,子序列的要求的包涵所有知识点都有的页数,且子序列的长度要最短。

首先我们并不知道总共有多少个知识点,这是个先要记录的。

不断的把序列中的元素加入到子序列中,知识点的数目会不断的增加,当知识点是数目满了之后,把子序列前面的元素开始剔除,再看看现在的子序列还是否满足这个条件。满足继续删除子序列前面的元素,否则的话把后面的元素加入到子序列中。

注意中间过程知识点数的增加或减少的维护。

#include<iostream>#include<cstring>#include<cstdio>#include<string>#include<algorithm>#include<set>#include<map>using namespace std;const int INF = 0x3f3f3f3f;const int vMax = 100010;int P[vMax];int main(){    #ifdef LOCAL        freopen("in.txt","r",stdin);    #endif // LOCAL    int n;    while(scanf("%d",&n) != EOF)    {        memset(P,0,sizeof(P));        set<int>all;        for(int i = 1; i <= n ; i++)        {            scanf("%d",&P[i]);            all.insert(P[i]);//set记录所有的知识点        }        map<int,int>cnt;        int sta = 1,fin = 0;        int t = 0 ;        int res = n;        while(1)        {            while(t < all.size() && fin <= n)            {                if(cnt[P[++fin]] ++ == 0)                {                    t++;//新知识点                }            }            if(t < all.size())            {                break;            }            res = min(res,fin - sta+1);            if(--cnt[P[sta++]] == 0)//知识点数目减少            {                t--;            }        }        printf("%d\n",res);    }    return 0;}


0 0
原创粉丝点击