WINDOW(单调队列的应用)

给你一个长度为 N 的数组,一个长为 K 的滑动的窗体从最左移至最右端,
你只能见到窗口的K个数,每次窗体向右移动一位,如下表:

你的任务是找出窗口在各位置时的 max value,min value.

INPUT:

第 1 行 n,k,

20%:n<=500;  
50%:  n<=100000;
100%:  n<=1000000;
第 2 行为长度为 n 的数组

8 3
1 3 -1 -3 5 3 6 7

OUTPUT:

2 行,
第 1 行每个位置的 min value,
第 2 行每个位置的 max value

-1 -3 -3 -3 3 3
3 3 5 5 6 7

题解:

如果每次都要sort的话,小数据可以O(n*k),但是数据大的话一定会超时。

那么该如何搞呢?  单调队列。O(n)效率很高!!

单调队列,一个元素单调的队列,可以保证队头是最小(最大)的;

可以通过队首删除,队尾插入来维护最优值。

这道题,就是通过单调队列来维护一个最大值和最小值。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<string>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<cstdlib>
 9 #include<iomanip>
10 #include<ctime>
11 using namespace std;
12 const int maxn=5000001;
13 int n,k;
14 int a[maxn],q[maxn];
15 int tail=0,head=0;
16
17 int main()
18 {
19     cin>>n>>k;
20     for(int i=1;i<=n;i++)
21         cin>>a[i];
22     q[tail]=1;
23     for(int i=2;i<k;i++)
24     {
25         while(a[i]<a[q[tail]]&&tail>=head)
26         {
27             tail--;
28         }
29         q[++tail]=i;
30     }
31     for(int i=k;i<=n;i++)
32     {
33         if(i-q[head]==k)    head++;
34         while(a[i]<a[q[tail]]&&tail>=head)
35         {
36             tail--;
37         }
38         q[++tail]=i;
39         cout<<a[q[head]]<<" ";
40     }
41     cout<<endl;
42     memset(q,0,sizeof(q));
43     head=0,tail=0;
44     q[tail]=1;
45     for(int i=2;i<k;i++)
46     {
47         while(a[i]>a[q[tail]]&&tail>=head)
48         {
49             tail--;
50         }
51         q[++tail]=i;
52     }
53     for(int i=k;i<=n;i++)
54     {
55         if(i-q[head]==k)    head++;
56         while(a[i]>a[q[tail]]&&tail>=head)
57         {
58             tail--;
59         }
60         q[++tail]=i;
61         cout<<a[q[head]]<<" ";
62     }
63     cout<<endl;
64     return 0;
65 }

时间: 2024-11-02 18:43:07

WINDOW(单调队列的应用)的相关文章

POJ 2823 Sliding Window 单调队列题解

本题是单调队列题解的入门,当然也可以使用RMQ 和 线段树,不过速度都没有单调队列那么快. 单调队列难点: 1 如何入列,保存数据 -- 最小单调队列的时候, 所有数都入列一次,在新的数据准备入列的时候,增加判断,如果当前数值小于队尾数值,那么队尾数值就出列.空队列的时候直接入列. 2 保存的数列是什么样的? 举例吧: 1 3 -1 -3 5 3 6 7 构建最小单调队列 第一个数值1的时候,空队列,那么入列,得到: 1 第二个数值3, 因为大于1:那么1不用出列,直接入列,得到: 1 3 第三

poj 2823 Sliding Window 单调队列或线段树

题目链接:http://poj.org/problem?id=2823 Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 38315   Accepted: 11350 Case Time Limit: 5000MS Description An array of size n ≤ 106 is given to you. There is a sliding window of size k

POJ2823 Sliding Window(单调队列)

单调队列,我用deque维护.这道题不难写,我第二次写单调队列,1次AC. ----------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<deque> #define rep(i,r) for(int i=0;i<r;i++) #define clr(x,c) memset

poj 2823 Sliding Window (单调队列)

Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 46705   Accepted: 13485 Case Time Limit: 5000MS Description An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left

poj 2823 Sliding Window (单调队列入门)

1 /***************************************************************** 2 题目: Sliding Window(poj 2823) 3 链接: http://poj.org/problem?id=2823 4 题意: 给一个数列,找所有连续k个数的最小值和最大值. 5 算法: 单调队列(入门) 6 ******************************************************************

POJ2823 Sliding Window (单调队列的基本应用)

题目链接: http://poj.org/problem?id=2823 题意: 给定一个长度为n的序列,求每个长度为k的区间的最大值与最小值 分析: 单调队列的基本应用 代码如下: <span style="font-size:14px;">#include <iostream> #include <cstring> #include <cstdio> #include <queue> #include <vector

poj2823Sliding Window——单调队列

题目:http://poj.org/problem?id=2823 单调队列模板. 代码如下: #include<iostream> #include<cstdio> using namespace std; int n,k,a[1000005],mx[1000005],mn[1000005]; int main() { scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) { scanf("%d&

POJ2823.Sliding Window——单调队列

http://poj.org/problem?id=2823 求长度为k的子序列里面的最大值,最小值 #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <algorithm> #define pk push_back const int INF = 0x3f3f3f3f; const int maxn = 1000010; usi

[ACM] poj 2823 Sliding Window(单调队列)

Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 36212   Accepted: 10723 Case Time Limit: 5000MS Description An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left

POJ2823 Sliding Window (单调队列)

POJ2823 Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 38342   Accepted: 11359 Case Time Limit: 5000MS Description An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the ve