zoukankan      html  css  js  c++  java
  • 逛画展(双指针)

    题意

    博览馆正在展出由世上最佳的 (M) 位画家所画的(N)幅图画。可是,那里的博览馆有一个很奇怪的规定,就是在购买门票时必须说明两个数字,(a)(b),代表他要看展览中的第 (a) 幅至第 (b) 幅画(包含 (a)(b))之间的所有图画,而门票的价钱就是一张图画一元。

    为了看到更多名师的画,你希望入场后可以看到所有名师的图画(至少各一张)。可是你又想节省金钱。。。

    请你写一个程序决定购买门票时的 (a) 值和 (b) 值。数据保证有解,如果存在多个解,则输出 (a) 最小的那个解。

    数据范围

    (1 leq N leq 1000000)

    (1 leq M leq 2000)

    思路

    很明显的双指针,就是右指针每往前推进一个单位,左指针指向的元素如果在这段序列中出现了不止(1)次,那么左指针可以往前推进。

    序列中每个画家有几幅作品可以通过维护一个数组实现。

    判断是否满足条件,可以记录一个(sum),新出现一个画家,那么(sum + 1)。当(sum = m)时,说明满足条件了。

    序列中作品的数量可以用左右指针的距离来判断。

    代码

    #include <iostream>
    #include <cstdio>
    
    using namespace std;
    
    const int N = 1000010, M = 2010;
    
    int n, m;
    int a[N], q[N];
    int cnt[M];
    
    int main()
    {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
        int hh = 0, tt = -1;
        int l = 1, r = n;
        int sum = 0;
        for(int i = 1; i <= n; i ++) {
            if(!cnt[a[i]]) sum ++;
            cnt[a[i]] ++;
            while(tt >= hh && cnt[a[q[hh]]] >= 2) {
                cnt[a[q[hh]]] --;
                hh ++;
            }
            q[++ tt] = i;
            if(sum == m && q[tt] - q[hh] < r - l) {
                l = q[hh], r = q[tt];
            }
        }
        printf("%d %d
    ", l, r);
        return 0;
    }
    
  • 相关阅读:
    Ngnix(三)—— window下布置nginx服务集群
    Java基础(一)—— 网络编程(一)—— Java Socket总结
    2018新浪Java笔试总结
    java yyyyMMddHHmmss格式字符串转换为yyyy-MM-dd HH:mm:ss格式字符串
    c# 返回多个参数(利用Tuple)
    c# 域名转换成ip地址
    myhaits if test判断字符串
    java中List转换成Json
    java打包发布程序.jar(Eclipse)
    redis设置密码
  • 原文地址:https://www.cnblogs.com/miraclepbc/p/14459485.html
Copyright © 2011-2022 走看看