码迷,mamicode.com
首页 > 其他好文 > 详细

P1638 逛画展

时间:2018-10-13 02:36:11      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:class   英文名   while   for   nsa   条件   两个指针   复杂   std   

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;
}

P1638 逛画展

标签:class   英文名   while   for   nsa   条件   两个指针   复杂   std   

原文地址:https://www.cnblogs.com/Garen-Wang/p/9780959.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!