題目鏈結
題目
給定乙個大小為n≤10^6的陣列。
有乙個大小為k的滑動視窗,它從陣列的最左邊移動到最右邊。
您只能在視窗中看到k個數字。
每次滑動視窗向右移動乙個位置。
以下是乙個例子:
該陣列為[1 3 -1 -3 5 3 6 7],k為3。
視窗位置
最小值最大值
[1 3 -1] -3 5 3 6 7
-1-3
1 [3 -1 -3] 5 3 6 7-33
1 3 [-1 -3 5] 3 6 7-35
1 3 -1 [-3 5 3] 6 7-35
1 3 -1 -3 [5 3 6] 736
1 3 -1 -3 5 [3 6 7]37
您的任務是確定滑動視窗位於每個位置時,視窗中的最大值和最小值。
輸入格式
輸入包含兩行。
第一行包含兩個整數n和k,分別代表陣列長度和滑動視窗的長度。
第二行有n個整數,代表陣列的具體數值。
同行資料之間用空格隔開。
輸出格式
輸出包含兩個。
第一行輸出,從左至右,每個位置滑動視窗中的最小值。
第二行輸出,從左至右,每個位置滑動視窗中的最大值。
輸入樣例:
8 3
1 3 -1 -3 5 3 6 7
輸出樣例:
-1 -3 -3 -3 3 3
3 3 5 5 6 7
單調佇列的板子題。不過也可以用multiset做。單調佇列複雜度o(n).multiset複雜度o(nlogn)
用陣列模擬佇列,q[maxn], hh表示隊頭,tt表示隊尾。
初始化:hh=0,tt=-1. hh>tt隊列為空,hh<=tt佇列非空。
入隊從隊尾入: q[++tt]=i;
佇列裡放的是下標
求區間最小值那麼維護佇列單調嚴格遞增,隊頭元素就是當前區間的最小值的陣列下標
求區間最小值那麼維護佇列單調嚴格遞減,隊頭元素就是當前區間的最大值的陣列下標
#include#include #include#include using namespace std;
typedef long long ll;
const int maxn=1e6+5;
int a[maxn];
int q[maxn];
int main()
cout<=m-1) printf("%d ",a[q[hh]]);
}return 0;
}
因為元素有重複值,每次只刪除重複值中的乙個,那麼要根據位址刪。
#include#include#include #include#include#include using namespace std;
typedef long long ll;
const int maxn=1e6+5;
multisets;
int a[maxn];
vectorans,ans2;
int main()
for(int i=0;ifor(int i=k-1;ifor(int i=0;icout
}
單調佇列 滑動視窗
nkoj 2152 description 給你乙個長度為n n 10 6 的陣列,乙個長為k的滑動的窗體從最左移至最右端,你只能見到視窗的k個數,每次窗體向右移動一位,找出窗體所包含的數字的最大和最小值,如下表所示 k的值為3 視窗位置 最小值 最大值 1 3 1 3 5 3 6 7 1 3 1 ...
滑動視窗 單調佇列
給定乙個大小為n 106的陣列。有乙個大小為k的滑動視窗,它從陣列的最左邊移動到最右邊。您只能在視窗中看到k個數字。每次滑動視窗向右移動乙個位置。以下是乙個例子 該陣列為 1 3 1 3 5 3 6 7 k為3。視窗位置 最小值 最大值 1 3 1 3 5 3 6 7 1 3 1 3 1 3 5 3...
單調佇列 滑動視窗
p1886 滑動視窗 模板 單調佇列 有乙個長為 n 的序列 a,以及乙個大小為 k 的視窗。現在這個從左邊開始向右滑動,每次滑動乙個單位,求出每次滑動後視窗中的最大值和最小值。如果按照暴力方法做的話,每一次判斷相鄰的k個數的最大值和最小值,複雜度為o n k 肯定會超時,因此就想到把每次的最大值和...