P1638 逛画展

two pointers练习题。

这道题求的是一个最短的区间长度,满足其中所有的数字都出现。

暴力的做法是两次枚举,复杂度\(O(n^2)\)

更优美的是尺取法,英文名叫two pointers。(两个指针。。。)

算法大概的过程是这样的:

while(左指针不越界)
{
    while(不满足题目条件 && 右指针不越界)
    {
        右指针++
        加入右指针所指元素
    }
    更新答案
    删除掉左指针所指元素
    左指针++
}

其实真的是很优美的,代码也很短。

希望我能真的学会吧。。。

代码:

#include<cstdio>

const int maxn = 1000005;
int a[maxn];
int vis[maxn];
int cnt, ansa, ansb = maxn;
int n, m;
int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    int l = 1, r = 1;
    vis[a[1]]++; cnt++;
    while(l <= n)
    {
        while(cnt != m)
        {
            r++;
            if(r > n) break;
            if(!vis[a[r]]) cnt++;
            vis[a[r]]++;
        }
        if(r - l + 1 < ansb - ansa + 1)
        {
            ansa = l; ansb = r;
        }
        if(vis[a[l]] == 1) cnt--;
        vis[a[l]]--;
        l++;
    }
    printf("%d %d\n", ansa, ansb);
    return 0;
}
posted @ 2018-10-12 22:01  Garen-Wang  阅读(240)  评论(0编辑  收藏  举报