zoukankan      html  css  js  c++  java
  • 洛谷P1638 逛画展 题解 尺取法/双指针/队列

    题目链接:https://www.luogu.com.cn/problem/P1638
    题目大意:
    给你一个长度为 \(n (\le 10^6)\) 的数组,数组中每个元素的范围在 \(1\)\(m\) 之间(\(1 \le m \le 2000\)),
    求一个最短的连续子序列包含 \(1\)\(m\) 内的所有元素。
    解题思路:
    这道题目我的解法是开一个队列,队列里面的元素是连续的。
    那么怎么保证这个队列是连续的呢?
    我只需要从 1 到 n 将每个元素入队,然后在需要的时候讲队首元素出队列。
    但是不能单纯地入队出队。
    我们开一个数组 \(c[i]\) 来表示第 \(i\) 位玩画家在队列中出现的次数,开一个变量 \(cnt\) 用于统计当前队列中有多少个不同的画家。
    然后我们从 1 到 n 遍历 i ,对于每个 i,我们在令 \(a_i\) 入队的同时令 \(c[a_i] ++\)
    此时若 \(c[a_i]\) 刚刚变为1,则说明编号为 \(a_i\) 的画家是第一次入队的,则我们令 \(cnt ++\) ,若此时 \(cnt\) 还没有等于 \(m\) ,说明还没有凑齐 \(m\) 个画家;
    若此时 \(cnt == m\) 了,说明以第 \(i\) 个画家结尾的连续 que.size() 幅画凑成了 m 个画家。
    但是这个时候并不一定是最优的结果,此时我们还要去判断:
    如果当前队首元素对应的画家的画(假设为 \(a_j\) )出现的次数 \(\lt 1\) ,说明以 \(a_i\) 结尾的画去掉队列最前面的那副画也是能凑够 m 个画家的,那么我们就可以去掉队首的元素。
    我们一直循环这样的操作指导队首元素不能出队列为止(即队首元素 \(a_j\) 对应的 \(c[a_j] == 0\) ,此时不能去掉它),此时的 que.size() 就是我们的一个备选答案。
    我们的目的就是寻找所有备选答案中的最小值。

    在这里我是使用队列queue来实现这个功能的。
    我们也可以开两个指针(坐标)来解决这个问题,开两个指针的方法在国内被叫做尺取法,在国外被叫做“two points”,所以我就直接翻译成“双指针”了。

    队列方式实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1000010, maxm = 2020;
    int m, c[maxm], cnt, ans = INT_MAX, n, a[maxn], ans_a, ans_b;
    queue<int> que;
    int main() {
        cin >> n >> m;
        for (int i = 1; i <= n; i ++) cin >> a[i];
        for (int i = 1; i <= n; i ++) {
            que.push(i);
            c[ a[i] ] ++;
            if (c[ a[i] ] == 1) cnt ++;
            while (!que.empty() && c[ a[que.front()] ] > 1) {
                c[ a[que.front()] ] --;
                que.pop();
            }
            if (cnt == m && que.size() < ans) {
                ans = que.size();
                ans_a = que.front();
                ans_b = que.back();
            }
        }
        cout << ans_a << " " << ans_b << endl;
        return 0;
    }
    
  • 相关阅读:
    Ubutun 安装oh-my-zsh
    归并算法
    3n+1问题
    插入排序
    二分查找
    rehl7配置本地yum仓库
    解决Anaconda3报错:AttributeError: '_NamespacePath' object has no attribute 'sort'
    深度学习情感分析(随机梯度下降代码实现)
    MySQL中创建数据库/表(外键约束),向表中插入数据
    python---利用unittestreport模块输出测试报告
  • 原文地址:https://www.cnblogs.com/quanjun/p/11929624.html
Copyright © 2011-2022 走看看