專題學習1 - I - 滑動視窗
阿新 • • 發佈:2022-03-28
題意
給一個長度為 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
輸出格式
第一行為滑動視窗從左向右移動到每個位置時的最小值,每個數之間用一個空格分開;
第二行為滑動視窗從左向右移動到每個位置時的最大值,每個數之間用一個空格分開。
思路
單項佇列模板題。
程式碼
#include <iostream> using namespace std; const int N = 5 + 1e6; int a[N]; int q1[N], q2[N]; int main() { int n, m, hh, tt; cin >> n >> m; for (int i = 1; i <= n; i++) scanf("%d", &a[i]); //min_deque hh = 1, tt = 0; for (int i = 1; i <= n; i++) { while (hh <= tt && q1[hh] + m <= i) hh++; while (hh <= tt && a[i] < a[q1[tt]]) tt--; q1[++tt] = i; if (i >= m) printf("%d ", a[q1[hh]]); } cout << '\n'; //max_deque hh = 1, tt = 0; for (int i = 1; i <= n; i++) { while (hh <= tt && q2[hh] + m <= i) hh++; while (hh <= tt && a[i] > a[q2[tt]]) tt--; q2[++tt] = i; if (i >= m) printf("%d ", a[q2[hh]]); } cout << '\n'; return 0; }