poj 3320 尺取法

来源:互联网 发布:武器大师原来的数据 编辑:程序博客网 时间:2024/04/27 22:37

链接:http://poj.org/problem?id=3320
还是运用尺取法的思路。
思路:
将头往前走,如果这个知识点没有出现过,将已有的知识点数量+1。如果覆盖了所有知识点,更新当前的最少页数。此时在判断尾巴出现的知识点是否出现超过一次,如果超过一次,那么就将尾巴往前移。因为如果没有超过一次也往前移的话,那么知识点就会少一个,导致之后头要往前移才有可能再次覆盖所有知识点,才可能再次更新。所以这其实并不一定要这样做,只有出现知识点重复的时候再将尾巴向前移动就可以。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <set>#include <map>using namespace std;#define M 1000000#define INF 0x3f3f3f3fint a[M];int main(){    int n;    while(scanf("%d",&n)==1)    {        map<int,int> mp;        set<int> s;        for(int i = 0;i < n;i++)        {            scanf("%d",&a[i]);            s.insert(a[i]);            mp[a[i]]++;        }        int total = s.size();        int st = 0, en = 0;        int ans = INF;        map<int,int> mp1;        int num = 0;        for(en = 0;en < n;en++)        {            if(mp1[a[en]] == 0)                num++;            mp1[a[en]]++;            while(num == total)            {                ans = min(ans,en-st+1);                if(mp1[a[st]]>1)                {                    mp1[a[st]]--;                    st++;  //如果该知识点出现超过1次,将尾巴移动一个                }                else break;            }        }        printf("%d\n",ans);    }    return 0;}
0 0