openjudge滑動視窗 遞增遞減佇列

2021-12-29 21:39:47 字數 1989 閱讀 2561

滑動視窗(from openjudge)

解決這個問題的時候,會碰到超時的問題。在資料量很大的情況下,不難想到需要用scanf和printf進行輸入輸出,但是即便是這樣也會導致超時,所以就需要在演算法上做出改變。這也就是這道題的重點:遞增/遞減佇列。

謂遞增(遞減)佇列想要實現的就是佇列中的元素是有序排列的。在一開始我們會想要直接利用stl庫中的優先佇列實現這個事情,但是問題在於我們難以進入到優先佇列的中間進行操作,只能對頭和尾進行操作,在面對這個題裡面對於視窗長度的限制的時候很難完成任務,所以我們選擇自己實現乙個雙端佇列的遞增(遞減)佇列結構。  

個結構模擬乙個佇列,利用val儲存資料,front代表佇列頭,back代表佇列尾,在隊列為空的時候front=back。在這個佇列中最核心的操作就是push。push的作用是加入乙個新元素。在本題中,以隊頭元素最大的隊列為例,push需要實現如下的工作:首先,如果從隊頭開始的元素已經在視窗範圍之外,那麼就將其刪除(front+1);其次,如果從隊尾開始的元素小於我們現在要加入佇列的數,那麼將其出佇列(back-1)。   

在處理的過程中,需要注意以下兩個問題:

1. 因為是對陣列中的數字操作,為了實現判斷數字是否在視窗之內,我們在佇列中儲存的是數字在陣列中的索引(具體可看**實現)

2. 注意在實現從隊首、隊尾操作過程中的邊界判斷(front)

**實現如下

#include

#include

#include

using namespace std;

const int n = 2000000;

int num[n/2]; /*儲存輸入資料*/

int ansup[n/2]; /*儲存視窗中的大元素答案*/

int ansdown[n/2]; /*儲存視窗中的小元素答案*/

//遞減佇列,找大元素

struct queueup

//x傳入的是在num中的索引

int push(int x)

int tmp = num[x];

//刪掉視窗外的元素

while (front < back && x - val[front] >= window)

front++;

//刪掉從末尾開始的小元素

while (back - 1 >= front && tmp >= num[val[back - 1]])

back--;

val[back] = x;

back++;

return val[front];

}};//遞增佇列,找小元素

struct queuedown

//x傳入的是在num中的索引

int push(int x)

int tmp = num[x];

while (front < back && x - val[front] >= window)

front++;

while (back - 1 >= front && tmp <= num[val[back - 1]])

back--;

val[back] = x;

back++;

return val[front];

}};int main()

int count = 0;

for (int i = k - 1; i < n; i++)

for (int i = 0; i < count; i++)

printf("%d ", num[ansdown[i]]);

cout << endl;

for (int i = 0; i < count; i++)

printf("%d ", num[ansup[i]]);

cout << endl;

return 0;

}至此完結~~

Leetcode 最小調整數 滑動視窗遞增子串行

給定乙個長度為n的陣列,以及乙個乘積值b,每次只能對乙個數增大或減少乙個單位,問最少多少次使得陣列乘積為b 思路 要使得調整的次數最少,那麼最開始調整的那個數字,應該是最小的數。貪心策略 選最小的數調整,其它部分數乘積最大 自己需要調整的偏移值就盡可能小 先對原先陣列從小到大排序。對於k 如果 b ...

Week5 D 滑動視窗滑動視窗

week5 d 滑動視窗滑動視窗 zjm 有乙個長度為 n 的數列和乙個大小為 k 的視窗,視窗可以在數列上來回移動.現在 zjm 想知道在視窗從左往右滑的時候,每次視窗內數的最大值和最小值分別是多少.例如 數列是 1 3 1 3 5 3 6 7 其中 k 等於 3.window position ...

week5 D 滑動視窗滑動視窗

zjm 有乙個長度為 n 的數列和乙個大小為 k 的視窗,視窗可以在數列上來回移動.現在 zjm 想知道在視窗從左往右滑的時候,每次視窗內數的最大值和最小值分別是多少.例如 數列是 1 3 1 3 5 3 6 7 其中 k 等於 3.window position minimum value max...