2022GDUT寒训专题一I题
题目
题面
给一个长度为 N的数组,一个长为 K的滑动窗体从最左端移至最右端,你只能看到窗口中的 K 个数,每次窗体向右移动一位,如下图:
| 窗口位置 | 最小值 | 最大值 |
|---|---|---|
| [1 3 -1] -3 5 3 6 7 | -1 | 3 |
| 1 [3 -1 -3] 5 3 6 7 | -3 | 3 |
| 1 3 [-1 -3 5] 3 6 7 | -3 | 5 |
| 1 3 -1 [-3 5 3] 6 7 | -3 | 5 |
| 1 3 -1 -3 [5 3 6] 7 | 3 | 6 |
| 1 3 -1 -3 5 [3 6 7] | 3 | 7 |
你的任务是找出窗体在各个位置时的最大值和最小值。
输入格式
第 1 行:两个整数 N 和 K; 第 2 行:N个整数,表示数组的 N个元素(≤2e9);
输出格式
第一行为滑动窗口从左向右移动到每个位置时的最小值,每个数之间用一个空格分开; 第二行为滑动窗口从左向右移动到每个位置时的最大值,每个数之间用一个空格分开。
样例
Input&Output
8 3
1 3 -1 -3 5 3 6 7
-1 -3 -3 -3 3 3
3 3 5 5 6 7
思路
这题是滑动窗口找最值问题,我们需要用到的工具是双头的单调队列。
若找的是最大值,则要构造一个递减的队列,反之递增。
解释如下:
1、首先明确我们遍历数组时,当前下标的意思为滑动窗口的右端点为该元素。记滑动窗口大小为k。
2、假设存在滑动窗口右端点a,记滑动窗口下一个元素为b,对于ab二者我们有两种情况:b>=a或者b<a(分别对应第3和4点)。
3、b>=a:我们知道b在a的右边,那么b影响的范围是[b,b+k-1],a影响的范围是[a,a+k-1]。因为b-a=1,所以b影响的范围始终比a影响的范围大。这意味着,一旦我们能走到b点,a就不再是最大值了,此时a已经没有了任何作用,a从队首出队。在a之前还有a-1,a-2......他们能影响的范围比a还要小,更不可能成为最大值,所以同理他们也从队首出队。一直到队列为空,现在b为新的最大值,为队首。
4、b<a:b更小,所以b没办法取代a,但是b有可能在a影响不到的地方也就是b+k-1这个点成为新的最大值,所以我们让b从队尾入队,可以理解为“待使用”。这里要注意的是b从队尾入队的时候也要遵循3中的原则,所以如果b比队尾元素大,那队尾元素也没有用了,我们也是将队尾元素出队,一直到b比队尾元素小停止。
5、还需要注意的一点是,滑动窗口是有大小的,所以我们队列中的元素是有“生命周期”的,也就是当前下标-队列元素下标+1要小于等于k
所以我们实际上队列存的是下标,这样引用起来比较方便。
代码
1 #include <iostream>
2 #include <algorithm>
3 using namespace std;
4 //这题是滑动窗口找最大或最小值的问题
5 //要运用到双头单调队列,一直维护最大或最小值,并且由于是滑动窗口所以元素存在生命周期,这里用数组q模拟
6 //
7 int num[1000010];
8 int q[4000020];
9 int main()
10 {
11 ios_base::sync_with_stdio(false);
12 cin.tie(NULL);cout.tie(NULL);
13 //
14 int n, k;cin >> n >> k;
15 for(int i = 0;i < n;++i) cin >> num[i];
16 //
17 int head, tail;
18 //最小值
19 head = 0, tail = 0;
20 //先让第一个元素入队
21 q[head] = 0;
22 for(int i = 0;i < n;++i)
23 {
24 //如果队首元素达到了生命周期,那么队首元素出队直到头尾指针相遇
25 while(head <= tail && i-q[head]+1 > k) head++;
26 if(num[q[head]] >= num[i])
27 {
28 //如果说你比这个队首元素还要小,那么一直出队
29 while(head <= tail && num[q[head]] >= num[i]) head++;
30 //走多了一格,要回去一格
31 q[--head] = i;
32 }else
33 {
34 //否则从队尾入队,但要维护单调性
35 while(head < tail && num[q[tail]] >= num[i]) tail--;
36 q[++tail] = i;
37 }
38 //当且仅当你达到所求滑动窗口大小的时候才能输出
39 if(i >= k-1) printf("%d ", num[q[head]]);
40 }
41 printf("\n");
42 //最大值
43 head = 0, tail = 0;
44 q[head] = 0;
45 for(int i = 0;i < n;++i)
46 {
47 while(head <= tail && i-q[head]+1 > k) head++;
48 if(num[q[head]] <= num[i])
49 {
50 while(head <= tail && num[q[head]] <= num[i]) head++;
51 q[--head] = i;
52 }else
53 {
54 while(head < tail && num[q[tail]] <= num[i]) tail--;
55 q[++tail] = i;
56 }
57 if(i >= k-1) printf("%d ", num[q[head]]);
58 }
59 printf("\n");
60 return 0;
61 }
62 //
2022GDUT寒训专题一I题的更多相关文章
- 2022GDUT寒训专题一J题
题目 题面 给你一个长度为 n的整数序列{A1,A2,⋯,A**n},要求从中找出一段连续的长度不超过 m的非空子序列,使得这个序列的和最大. 输入格式 第一行为两个整数 n,m: 第二行为 n个用空 ...
- 2022GDUT寒训专题一C题
题目 题面 马在中国象棋以日字形规则移动. 请编写一段程序,给定n×m大小的棋盘,以及马的初始位置 (x, y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点. 输入格式 ...
- X-NUCA 2017 web专题赛训练题 阳光总在风雨后和default wp
0X0.前言 X-NUCA 2017来了,想起2016 web专题赛,题目都打不开,希望这次主办方能够搞好点吧!还没开赛,依照惯例会有赛前指导,放一些训练题让CTFer们好感受一下题目. 题目有一大 ...
- 专题:DP杂题1
A POJ 1018 Communication System B POJ 1050 To the Max C POJ 1083 Moving Tables D POJ 1125 Stockbroke ...
- 恶补一下DP+背包专题(刷刷水题)L2
开心的金明 题目大意 就是求一定背包容量的最大值 思路 想必大家都知道,一看到这种题目,就会想起01背包 虽然特别简单但是还是讲一下吧 状态设置 由于这题差不多是一个01背包的版子题,那么我们就只需要 ...
- 7专题总结-高频题high frequency
Outline . Single Number I, II, III . Majority Number I, II, III . Best Time to Buy and Sale Stock I, ...
- 多校寒训TaoTao要吃鸡dp
题目描述 Taotao的电脑带不动绝地求生,所以taotao只能去玩pc版的荒野行动了, 和绝地求生一样,游戏人物本身可以携带一定重量m的物品,装备背包 之后可以多携带h(h为0代表没有装备背包)重量 ...
- 最小生成树 kuangbin专题最后一个题
题目链接:https://cn.vjudge.net/contest/66965#problem/N 注释:这道题需要用krustra,用prim的话可能会超时.并且在计算距离的时候要尽量减少步骤,具 ...
- 专题练习HDU题集 图论
[图论01]最短路 Start Time : 2018-01-02 12:45:00 End Time : 2018-01-23 12:45:00 Contest Status : Runnin ...
随机推荐
- python爬取信息到数据库与mysql简单的表操作
python 爬取豆瓣top250并导入到mysql数据库中 import pymysql import requests import re url='https://movie.douban.co ...
- 【LeetCode】277. Find the Celebrity 解题报告 (C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力 日期 题目地址:https://leetcode ...
- 【LeetCode】937. Reorder Log Files 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 分割和排序 日期 题目地址:https://leet ...
- 【LeetCode】336. Palindrome Pairs 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 HashTable 相似题目 参考资料 日期 题目地 ...
- Discrete Logging(poj2417)
Discrete Logging Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5120 Accepted: 2319 ...
- SOFA 数据透析
数据透传: 在 RPC调用中,数据的传递,是通过接口方法参数来传递的,需要接口方定义好一些参数允许传递才可以,在一些场景下,我们希望,能够更通用的传递一些参数,比如一些标识性的信息.业务方可能希望,在 ...
- 第三十个知识点:大致简述密钥协商中的BR安全定义。
第三十个知识点:大致简述密钥协商中的BR安全定义. 在两方之间建密钥共享是一件密码学中古老的问题.就算只考虑定义也比标准加密困难的多.尽管古典的Diffie-Hellman协议在1976年思路解决了这 ...
- [炼丹术]YOLOv5训练自定义数据集
YOLOv5训练自定义数据 一.开始之前的准备工作 克隆 repo 并在Python>=3.6.0环境中安装requirements.txt,包括PyTorch>=1.7.模型和数据集会从 ...
- javaScript系列 [09]-javaScript和JSON (拓展)
本文输出JSON搜索和JSON转换相关的内容,是对前两篇文章的补充. JSON搜索 在特定的开发场景中,如果服务器端返回的JSON数据异常复杂(可能超过上万行),那么必然就有对JSON文档进行搜索的需 ...
- Java初学者作业——使用switch结构实现一个简单的购物计划
返回本章节 返回作业目录 需求说明: 使用switch结构实现一个购物计划,计划为:星期一.星期三.星期五购买伊利牛奶和面包,星期二.星期四购买苹果和香蕉,星期六.星期日购买啤酒和周黑鸭. 实现思路: ...