POJ-3320 Jessica's Reading Problem(尺取法+离散化)

题意

给定一个长度为 n 的数组 a 代表一本书上的知识点,求覆盖到所有不同知识点的最小区间的长度。
1 n 1000000
a i i n t

思路

由于这类尺取需要开 c n t 数组实时记录一个数出现的次数,而这题 a i 的范围偏大,故使用离散化,然后就转化为上一题了

代码

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define FOR(i,x,y) for(int i=(x);i<=(y);i++)
#define DOR(i,x,y) for(int i=(x);i>=(y);i--)
typedef long long LL;
using namespace std;
int a[1000003],b[1000003];
int cnt[1000003];

int main()
{
    int n,elem;
    while(~scanf("%d",&n))
    {
        FOR(i,1,n)scanf("%d",&a[i]);
        FOR(i,1,n)b[i]=a[i];
        sort(b+1,b+1+n);
        elem=unique(b+1,b+1+n)-b-1;
        FOR(i,1,n)a[i]=lower_bound(b+1,b+1+elem,a[i])-b;
        int R=0,s=0,ans=2e9;
        FOR(L,1,n)
        {
            while(L>R||R<n&&s<elem)
            {
                if(cnt[a[++R]]==0)s++;
                cnt[a[R]]++;
            }
            if(R>n)break;
            if(s>=elem)ans=min(ans,R-L+1);
            cnt[a[L]]--;
            if(cnt[a[L]]==0)s--;
        }
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/paulliant/article/details/80868157