题目链接: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;
}

洛谷P1638 逛画展 题解 尺取法/双指针/队列的更多相关文章

  1. 洛谷P1638 逛画展 (尺取法)

    尺取法的经典题目: 博览馆正在展出由世上最佳的 mm 位画家所画的图画. 游客在购买门票时必须说明两个数字,aa 和 bb,代表他要看展览中的第 aa 幅至第 bb 幅画(包含 a,ba,b)之间的所 ...

  2. 洛谷 P1638 逛画展 题解

    P1638 逛画展 题目描述 博览馆正在展出由世上最佳的 M 位画家所画的图画. wangjy想到博览馆去看这几位大师的作品. 可是,那里的博览馆有一个很奇怪的规定,就是在购买门票时必须说明两个数字, ...

  3. [洛谷P1638]逛画展

    [洛谷P1638]逛画展 题目大意: 有\(n(n\le10^6)\)个格子,每个格子有一种颜色.颜色种数为\(m(m\le2000)\).求包含所有颜色的最小区间. 思路: 尺取法裸题. 思路: # ...

  4. 洛谷P1638逛画展

    传送门啦 只需记录满足条件的一个区间的初始端点 $ (head, tail) $ ,不断删掉左端点 $ head $ ,不断更新右端点 $ tail $ : 开一个 $ vis[] $ 记录一下每幅画 ...

  5. 洛谷P2832 行路难 分析+题解代码【玄学最短路】

    洛谷P2832 行路难 分析+题解代码[玄学最短路] 题目背景: 小X来到了山区,领略山林之乐.在他乐以忘忧之时,他突然发现,开学迫在眉睫 题目描述: 山区有n座山.山之间有m条羊肠小道,每条连接两座 ...

  6. 【洛谷P3960】列队题解

    [洛谷P3960]列队题解 题目链接 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m ...

  7. 洛谷P2312 解方程题解

    洛谷P2312 解方程题解 题目描述 已知多项式方程: \[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\] 求这个方程在 \([1,m]\) 内的整数解(\(n\) 和 \(m\) ...

  8. 洛谷P1577 切绳子题解

    洛谷P1577 切绳子题解 题目描述 有N条绳子,它们的长度分别为Li.如果从它们中切割出K条长度相同的 绳子,这K条绳子每条最长能有多长?答案保留到小数点后2位(直接舍掉2为后的小数). 输入输出格 ...

  9. 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)

    洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...

随机推荐

  1. H3C路由器Telnet服务配置命令

  2. Chrome接口请求一直是pending状态,但接口实际上是正常的

    1.现象 个别机器突然出现Chrome访问我司产品异常,本该通过接口获取的数据没有呈现,之前都是好好的,而且其他机器同样用同版本Chrome访问正常. 出现问题的机器重装Chrome问题依然存在,直到 ...

  3. 洛谷P1288 取数游戏II 题解 博弈论

    题目链接:https://www.luogu.org/problem/P1288 首先,如果你的一边的边是 \(0\) ,那么你肯定走另一边. 那么你走另一边绝对不能让这条边有剩余,因为这条边有剩余的 ...

  4. hdu 2126 Buy the souvenirs(记录总方案数的01背包)

    Buy the souvenirs Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  5. H3C RIP基本配置

  6. 如何理解springMVC?

    springMVC 工作原理? 简单理解:客户端发送请求-->前端控制器接受客户端的请求DispathServelt-->找到处理器映射HandMapping-->找到处理器hand ...

  7. H3C 链路聚合的作用

  8. es6笔记 day4---模块化

    模块化: 注意:需要放到服务器环境 1.如何定义模块? export  东西 export   const a = 12; export { a  as  aaa, b  as  banana } 2 ...

  9. C++动态数组中的C6385, C6386警告

    警告 C6385 从“m”中读取的数据无效: 可读大小为“col*sizeof(int)”个字节,但可能读取了“8”个字节. 警告 C6386 写入到“m”时缓冲区溢出: 可写大小为“col*size ...

  10. 【51.64%】【POJ 1330】Nearest Common Ancestors

    Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 26416 Accepted: 13641 Description A roote ...