挑战3.2.1 Jessica's Reading Problem (poj 3320)

题意

题目
就是说一共有p页,每一页有一个知识点(可以重复)。找出一些连续的页数,使得所有的知识点全部覆盖,求最小的连续页数

代码

#include <stdio.h>
#include <set>
#include <map>

using namespace std;

int point[10000005];
int main()
{
    int p;
    while (scanf("%d",&p)!=EOF)
    {
        set<int>a;
        for (int i=0;i<p;i++)
           {
                scanf("%d",&point[i]);
                a.insert(point[i]);
           }
        int n=a.size();            //求出总的知识点的数量

        int num=0;            //num指当前包含的知识点的种类数(最大为n)
        int s=0,t=0;         //s,t表示要求的连续页数的头指针和尾指针
        int res=p;           //res表示当前已知的最小连续页数
        map<int,int>count;    //count表示 个数【知识点】(某个知识点的个数)

        while(1)
        {
            while(t<p&&num<n)   //从0开始往后加,保证最后一页肯定比书的页数小。
            {
                if (count[point[t++]]++==0)   //count为零表示出现的新的知识点
                    num++;
            }
            if (num<n) break;
            res=min(res,t-s);
            if (--count[point[s++]]==0)   //减去最前面一页看能否有更小的页数出现
                num--;
        }
        printf("%d\n",res);
    }
    return 0;
}

一开始的目标长度为零,通过while(1)里面的第一个循环不断向后移动尾指针,使得所有的知识点都被包含。当n==num表示完全包含了就退出内层的while循环,到最下面的一个if语句如果减去前面一页(头指针后移)使得某个知识点不被包含了,然后继续看后面能不能有某页可以使得它被包含。并选择更少的那个页数。退出大循环的条件是——当头指针移过某页之后,即使其后的所有页数全部加上也无法包括某个知识点。在此之前一定有某个res是最少的且能包含所有的知识点。

猜你喜欢

转载自blog.csdn.net/cugsl/article/details/78168612